@fluidframework/core-interfaces 2.10.0 → 2.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/api-report/core-interfaces.beta.api.md +17 -0
  3. package/api-report/core-interfaces.legacy.alpha.api.md +17 -0
  4. package/api-report/core-interfaces.legacy.public.api.md +17 -0
  5. package/api-report/core-interfaces.public.api.md +17 -0
  6. package/dist/events/emitter.d.ts +60 -0
  7. package/dist/events/emitter.d.ts.map +1 -0
  8. package/dist/events/emitter.js +7 -0
  9. package/dist/events/emitter.js.map +1 -0
  10. package/dist/events/index.d.ts +7 -0
  11. package/dist/events/index.d.ts.map +1 -0
  12. package/dist/events/index.js +7 -0
  13. package/dist/events/index.js.map +1 -0
  14. package/dist/events/listeners.d.ts +76 -0
  15. package/dist/events/listeners.d.ts.map +1 -0
  16. package/dist/events/listeners.js +7 -0
  17. package/dist/events/listeners.js.map +1 -0
  18. package/dist/events.d.ts.map +1 -1
  19. package/dist/events.js.map +1 -1
  20. package/dist/index.d.ts +1 -0
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js.map +1 -1
  23. package/dist/legacy.d.ts +4 -0
  24. package/dist/public.d.ts +4 -0
  25. package/lib/events/emitter.d.ts +60 -0
  26. package/lib/events/emitter.d.ts.map +1 -0
  27. package/lib/events/emitter.js +6 -0
  28. package/lib/events/emitter.js.map +1 -0
  29. package/lib/events/index.d.ts +7 -0
  30. package/lib/events/index.d.ts.map +1 -0
  31. package/lib/events/index.js +6 -0
  32. package/lib/events/index.js.map +1 -0
  33. package/lib/events/listeners.d.ts +76 -0
  34. package/lib/events/listeners.d.ts.map +1 -0
  35. package/lib/events/listeners.js +6 -0
  36. package/lib/events/listeners.js.map +1 -0
  37. package/lib/events.d.ts.map +1 -1
  38. package/lib/events.js.map +1 -1
  39. package/lib/index.d.ts +1 -0
  40. package/lib/index.d.ts.map +1 -1
  41. package/lib/index.js.map +1 -1
  42. package/lib/legacy.d.ts +4 -0
  43. package/lib/public.d.ts +4 -0
  44. package/package.json +4 -4
  45. package/src/events/README.md +3 -0
  46. package/src/events/emitter.ts +73 -0
  47. package/src/events/index.ts +18 -0
  48. package/src/events/listeners.ts +80 -0
  49. package/src/events.ts +0 -1
  50. package/src/index.ts +11 -0
@@ -0,0 +1,73 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import type { Listeners } from "./listeners.js";
7
+
8
+ /**
9
+ * Interface for an event emitter that can emit typed events to subscribed listeners.
10
+ * @internal
11
+ */
12
+ export interface IEmitter<TListeners extends Listeners<TListeners>> {
13
+ /**
14
+ * Emits an event with the specified name and arguments, notifying all subscribers by calling their registered listener functions.
15
+ * @param eventName - The name of the event to fire
16
+ * @param args - The arguments passed to the event listener functions
17
+ */
18
+ emit<K extends keyof Listeners<TListeners>>(
19
+ eventName: K,
20
+ ...args: Parameters<TListeners[K]>
21
+ ): void;
22
+
23
+ /**
24
+ * Emits an event with the specified name and arguments, notifying all subscribers by calling their registered listener functions.
25
+ * It also collects the return values of all listeners into an array.
26
+ *
27
+ * @remarks
28
+ * Warning: This method should be used with caution. It deviates from the standard event-based integration pattern as creates substantial coupling between the emitter and its listeners.
29
+ * For the majority of use-cases it is recommended to use the standard {@link IEmitter.emit} functionality.
30
+ * @param eventName - The name of the event to fire
31
+ * @param args - The arguments passed to the event listener functions
32
+ * @returns An array of the return values of each listener, preserving the order listeners were called.
33
+ */
34
+ emitAndCollect<K extends keyof Listeners<TListeners>>(
35
+ eventName: K,
36
+ ...args: Parameters<TListeners[K]>
37
+ ): ReturnType<TListeners[K]>[];
38
+ }
39
+
40
+ /**
41
+ * Called when the last listener for a given `eventName` is removed.
42
+ * @remarks
43
+ * Useful for determining when to clean up resources related to detecting when the event might occurs.
44
+ * @internal
45
+ */
46
+ export type NoListenersCallback<TListeners extends object> = (
47
+ eventName: keyof Listeners<TListeners>,
48
+ ) => void;
49
+
50
+ /**
51
+ * Allows querying if an object has listeners.
52
+ * @sealed
53
+ * @internal
54
+ */
55
+ export interface HasListeners<TListeners extends Listeners<TListeners>> {
56
+ /**
57
+ * Determines whether or not any listeners are registered for the specified event name.
58
+ *
59
+ * @remarks
60
+ * If no event name is given, checks if *any* listeners are registered.
61
+ * This can be used to know when its safe to cleanup data-structures which only exist to fire events for their listeners.
62
+ */
63
+ hasListeners(eventName?: keyof Listeners<TListeners>): boolean;
64
+ }
65
+
66
+ /**
67
+ * Subset of Map interface including only the `get` and `set` methods.
68
+ * @internal
69
+ */
70
+ export interface MapGetSet<K, V> {
71
+ get(key: K): V | undefined;
72
+ set(key: K, value: V): void;
73
+ }
@@ -0,0 +1,18 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ export type {
7
+ HasListeners,
8
+ IEmitter,
9
+ MapGetSet,
10
+ NoListenersCallback,
11
+ } from "./emitter.js";
12
+
13
+ export type {
14
+ IsListener,
15
+ Listeners,
16
+ Listenable,
17
+ Off,
18
+ } from "./listeners.js";
@@ -0,0 +1,80 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ /**
7
+ * `true` iff the given type is an acceptable shape for a {@link Listeners | event} listener
8
+ * @public
9
+ */
10
+ export type IsListener<TListener> = TListener extends (...args: any[]) => void ? true : false;
11
+
12
+ /**
13
+ * Used to specify the kinds of events emitted by a {@link Listenable}.
14
+ *
15
+ * @remarks
16
+ * Any object type is a valid {@link Listeners}, but only the {@link IsListener | event-like} properties of that
17
+ * type will be included.
18
+ *
19
+ * @example
20
+ * ```typescript
21
+ * interface MyEvents {
22
+ * load: (user: string, data: IUserData) => void;
23
+ * error: (errorCode: number) => void;
24
+ * }
25
+ * ```
26
+ *
27
+ * @public
28
+ */
29
+ export type Listeners<T extends object> = {
30
+ [P in (string | symbol) & keyof T as IsListener<T[P]> extends true ? P : never]: T[P];
31
+ };
32
+
33
+ /**
34
+ * An object which allows the registration of listeners so that subscribers can be notified when an event happens.
35
+ * @param TListeners - All the {@link Listeners | events} that this subscribable supports
36
+ *
37
+ * @privateRemarks
38
+ * {@link @fluid-internal/client-utils#CustomEventEmitter} can be used as a base class to implement this via extension.
39
+ * ```ts
40
+ * type MyEventEmitter = IEmitter<{
41
+ * load: (user: string, data: IUserData) => void;
42
+ * error: (errorCode: number) => void;
43
+ * }>
44
+ * ```
45
+ * {@link @fluid-internal/client-utils#createEmitter} can help implement this interface via delegation.
46
+ *
47
+ * @sealed @public
48
+ */
49
+ export interface Listenable<TListeners extends object> {
50
+ /**
51
+ * Register an event listener.
52
+ * @param eventName - The name of the event.
53
+ * @param listener - The listener function to run when the event is fired.
54
+ * @returns A {@link Off | function} which will deregister the listener when called.
55
+ * Calling the deregistration function more than once will have no effect.
56
+ *
57
+ * Listeners may also be deregistered by passing the listener to {@link Listenable.off | off()}.
58
+ * @remarks Registering the exact same `listener` object for the same event more than once will throw an error.
59
+ * If registering the same listener for the same event multiple times is desired, consider using a wrapper function for the second subscription.
60
+ */
61
+ on<K extends keyof Listeners<TListeners>>(eventName: K, listener: TListeners[K]): Off;
62
+
63
+ /**
64
+ * Deregister an event listener.
65
+ * @param eventName - The name of the event.
66
+ * @param listener - The listener function to remove from the current set of event listeners.
67
+ * @remarks If `listener` is not currently registered, this method will have no effect.
68
+ *
69
+ * Listeners may also be deregistered by calling the {@link Off | deregistration function} returned when they are {@link Listenable.on | registered}.
70
+ */
71
+ off<K extends keyof Listeners<TListeners>>(eventName: K, listener: TListeners[K]): void;
72
+ }
73
+
74
+ /**
75
+ * A function that, when called, will deregister an event listener subscription that was previously registered.
76
+ * @remarks
77
+ * It is returned by the {@link Listenable.on | event registration function} when event registration occurs.
78
+ * @public
79
+ */
80
+ export type Off = () => void;
package/src/events.ts CHANGED
@@ -18,7 +18,6 @@ export interface IEvent {
18
18
  *
19
19
  * @eventProperty
20
20
  */
21
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
22
21
  (event: string, listener: (...args: any[]) => void);
23
22
  }
24
23
 
package/src/index.ts CHANGED
@@ -48,3 +48,14 @@ export type { FluidObjectProviderKeys, FluidObject, FluidObjectKeys } from "./pr
48
48
  export type { ConfigTypes, IConfigProviderBase } from "./config.js";
49
49
  export type { ISignalEnvelope } from "./messages.js";
50
50
  export type { ErasedType } from "./erasedType.js";
51
+
52
+ export type {
53
+ HasListeners,
54
+ IEmitter,
55
+ IsListener,
56
+ Listeners,
57
+ Listenable,
58
+ MapGetSet,
59
+ NoListenersCallback,
60
+ Off,
61
+ } from "./events/index.js";