This reverts commit 410ac73469.
The rationale is that the frontend can wrap its own components with a
disposable thread-safe wrapper that doesn't work once it's invalidated
if it wants the guarantee that the component doesn't work anymore once
the context is stopped.
This commit separated SetterMethods that are specifically for updating
containers to another method type, named ContainerUpdaterMethod. This
change is done to force a context parameter into container setters,
allowing the frontend to know if an incoming update is valid or not,
based on the state of the context given.
The validity check should be the same as any other context:
select {
case <-ctx.Done():
return
default:
addEvent()
}
It is crucial, however, to do the checking and updating in the same
thread or lock as the context is cancelled. This explicit
synchronization is required to prevent any race condition whatsoever
with cancellation of the context.
The backend must pass in the right context, that is, any context that
inherits the cancellation from the frontend. Passing in the invalid
context is undefined behavior and will eventually cause a data race.
This commit removes all stop callbacks in ContainerMethods. The
intention is to have backends disconnect callbacks when the context is
cancelled, rather than when the stop function is called.
This helps get rid of countless race condition flaws caused by the
duration between the context being cancelled on one thread and the stop
callback being set in another, causing the handlers to not disconnect.
This commit changes Configurator's methods to be SetterMethods instead
of IOMethods, as Configurator is specifically made for frontend-managed
settings just for the backend, so no storing/loading is needed on the
backend's side.
This commit also changes SetterMethod to allow methods done to the
backend to error out, in case the setting value is invalid somehow.
Setter methods that are called by the backend (as opposed to the
frontend) must never error.
This commit changes several ContainerMethods to take in a context. It
also changes all IOMethods to take in a context.
This addition adds consistency to the API as well as allowing better
graceful cancellation and cleanups if needed when, for example, the user
wants to discard an ongoing process.
This commit broke ListMember to remove the Namer interface. This is
because the whole interface should act as a static container with
information to be updated.
This commit breaks Nicknamer to embed Name instead of having its own
ContainerMethod with a similar function signature but different name.
This allows the frontend to reuse the same LabelContainer abstraction
for Nickname as well.
This commit breaks the Service interface to force all services to have a
global unique identifier. The commit does not enforce any particular
format, but the Reverse Domain Name Notation is recommended.
For reference:
https://en.wikipedia.org/wiki/Reverse_domain_name_notation
This commit breaks the previous Columnate API to return booleans instead
of constant integers. This makes handling Columnate API much simpler
with less false values (since all possible boolean values are valid).
This commit breaks ContainerMethod to enforce explicit destructors. This
gives the frontend explicit control over when the container is
unsubscribed, but it also eases unsubscription implementations in the
backend.
With this new change, the backend can now add the container into a
global repository and unsubscribe from it explicitly from the callback.
This commit breaks more of the API to force all implementations of Namer
to use a LabelContainer instead of just returning a text. This is done
to allow updating of all labels instead of having to update the whole
parent context. This allows the backend to do book-keeping of labels and
images and trivially update them simultaneously without updating the
parent context.
The Author interface is also renamed to User. This allows the user
interface to be used everywhere else outside of Message.
This commit introduced a big breaking change of changing Author and
Namer to no longer have any reference to Icon or Image containers and
interfaces.
Instead, in the case of Author and Namer, it relies on the label being
updated by either an update setter or LabelContainer. The frontend
should get the first image/avatar to display that instead.
This commit also added ReadIndicator and related interfaces to support
the read receipts feature seen in Matrix, Telegram, Messenger and co.
The UnreadIndicator interface was broken to add the MarkRead method,
which hands explicit control of setting read messages for the current
user to the frontend instead.
This commit added the Columnator interface. This interface accommodates
the fact that some services (such as Discord) stylizes certain nested
servers in the same column.
This commit also fixed a minor test case.
This commit changes IOMethods and clarifies stop functions that they
will act as destructors or disposers for whatever interface that
implements the methods, and that both the backend and frontend should
free that interface when they're called.
This commit is added as part of the IPC protocol.
This commit renamed Attachments to Attacher, as the new name is more
idiomatic.
This commit also added the Replier interface, which is used to indicate
that a message being sent is a reply towards something.
This commit added MessageReferencer for the text.Rich segments, which
allows a message to highlight a URL or text as a reference to other
messages. This could be used for replies as well as links that are
supposed to go to other messages.
The frontend gets to decide how exactly to represent the message when it
is clicked. However, as of right now, there is no API to fetch a single
message individually, so this API is limited to just within the message
buffer.
This commit clarifies that JoinServer must only be opened by one
container. In other words, before it is called again, the stop callback
of the last call must be called beforehand. This applies per messenger.
This commit reverts commit 9fd965d45a.
The reason for this reversion is that Send does not return an ID, and
therefore cannot know if any of its incoming messages are what it sent
or not.
Although a message return can be added into Send, that would be
extraneous, as the same message may now arrive by Send returning and/or
through the messenger container. Working around this would require
having an Upsert behavior instead of Insert or Update.
This commit deprecates all Nonce methods as well as the concept of
Nonces in general. This is because in certain cases where coordination
between message sends and echoes would require far too much effort with
nonces as a method to detect message arrivals.
Starting from this commit, frontend implementations must assume that a
nil error returned from Sender's Send method means that the message has
successfully arrived.
Backend implementations must provide this guarantee if necessary by
blocking Send until it's sure that the message has arrived. For services
that send messages asynchronously, a handler and a blocking channel
(or pubsub) could be used to signal to the Send goroutine from the event
loop that the message has arrived. Backends may choose to transmit its
own nonces for this purpose.
This commit broke both the cchat API and its repository generation API
to accomodate for custom error types, as the new Authenticator API now
uses AuthenticateError over error to add in multi-stage authentication
instead of the old method with the for loop.
This commit also removed the multistage example documented in
Authenticator, as the API is now clearer.
This commit also added the WrapAuthenticateError helper function that
wraps a normal error into an AuthenticateError that does not have a
NextStage return. Backends should use this for
This commit embeds the Namer interface into Authenticator as well as
adding the new Description method, both of which returns a text.Rich.
These methods are added to provide contextual clues to the user about
each Authenticator method.
Frontends can use the Name as the title, so the name should be short,
concise, and not include the name of the service.
This commit clarifies the rules regarding ID uniqueness and guarantees
when it comes to the backend and frontend. This piece of documentation
was added into the top package section.
This commit breaks the API to allow backends to return a slice of
Authenticators instead of a single Authenticator in the Service
interface. This is because some services might allow for more than one
method of authentication.
Note that the representation of multiple authenticators depends on the
frontend. One may choose to use tabs, notebooks, stacks, or anything
that is reasonable.
This commit adds the SplitFunc helper type which has a function
signature matching that of ArgsIndexer and SplitIndexer. Implementations
can use this type to provide pluggable splitters.
This commit clarified the word split rules when it comes to the
Commander interface. Specifically, this interface now has an edge case
of having split rules similarly to shell words (or shell syntax).
The implementation of these split rules is added into package split,
similarly to SplitIndexed. It is called ArgsIndexed. For the most parts,
it will behave similarly to shell syntax.
This commit breaks the Commander interface. Prior to this, the Run
method would take in an io.Writer and do its tasks in the background.
Although this has lots of potential for usages, it is also very
overkill. Moreover, it makes IPC harder, since it now has to send over
fragments of data in synchronized order.
This commit gets rid of the io.Writer and only take a []byte for return
along with the error. This makes it easier for both the frontend and
backend to implement most commands, as well as making it easier for data
to be transferred over the wire.
This commit clarifies text.Imager's (and therefore text.Avatarer's as
well) bound behaviors. Prior to this commit, it is unclear which end
bound an implementation should return. This commit clarifies that in
order for the image to be inlined, the start must overlap the end
bounds.
This clarification was needed in order to differentiate images to be
inlined with images to be associated with other contexts, such as
Mentioned. The inline check would therefore be very simple:
if start == end {
if imager := segment.AsImager(); imager != nil {
log.Println("Segment has an inline image.")
}
}
Note that since there's now a way to explicitly define whether an image
is inlined or not, for implementations that can't display images, the
ImageText() should only be used if the image is actually inlined.
Therefore, the same check also applies to ImageText(). This also applies
to AvatarText().
This commit fixes the implementation of the helper function SolidColor.
It now does correctly what it says: it sets the alpha bits to 0xFF.
Prior to this, the function would override part of the color due to an
incorrect shift.
Prior to this commit, the PreviousID method ambiguously confused two
different behaviors for the same result, that is when the returned ID is
empty.
This commit adds a return boolean to the method to differentiate those
two behaviors.
Prior to this commit, the PreviousID method of ServerUpdate seemed to be
a big unknown. This commit clarified that unknown by declaring two
conditions: when PreviousID returns an empty and non-empty ID.
The above change allows ServerUpdate events to both modify existing
servers as well as inserting new ones.
This commit breaks package split's API to take in int64 types instead of
int. This is because CompletionEntry now uses int64 over int for
concreteness.
This commit clarifies text.Imager and text.Avatarer's bound behaviors.
Prior to this, the only behavior that those two interfaces have
regarding bounds is that only the starting bound matters, because images
must not substitute texts.
This commit clarifies that images are allowed complement other sections.
For example, a Mentioner can "have" an Imager by having the bounds
overlap.
These details are intentionally vaguely defined (it doesn't list any
interfaces beyond Mentioner), so implementations of either side can
implement these however they want, as long as the bounds overlap.
In the future, further clarification rules may be added if needed.