@alwatr/signal 1.1.2 → 2.0.1

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 (65) hide show
  1. package/CHANGELOG.md +179 -163
  2. package/context.d.ts +31 -0
  3. package/context.d.ts.map +1 -0
  4. package/context.js +40 -0
  5. package/context.js.map +1 -0
  6. package/index.d.ts +6 -9
  7. package/index.d.ts.map +1 -1
  8. package/index.js +5 -16
  9. package/index.js.map +1 -1
  10. package/multithread-context.d.ts +21 -0
  11. package/multithread-context.d.ts.map +1 -0
  12. package/multithread-context.js +50 -0
  13. package/multithread-context.js.map +1 -0
  14. package/observable.d.ts +47 -0
  15. package/observable.d.ts.map +1 -0
  16. package/observable.js +127 -0
  17. package/observable.js.map +1 -0
  18. package/package.json +9 -9
  19. package/signal.d.ts +19 -0
  20. package/signal.d.ts.map +1 -0
  21. package/signal.js +23 -0
  22. package/signal.js.map +1 -0
  23. package/simple-signal.d.ts +19 -0
  24. package/simple-signal.d.ts.map +1 -0
  25. package/simple-signal.js +23 -0
  26. package/simple-signal.js.map +1 -0
  27. package/type.d.ts +15 -126
  28. package/type.d.ts.map +1 -1
  29. package/type.js.map +1 -1
  30. package/command-handler.d.ts +0 -25
  31. package/command-handler.d.ts.map +0 -1
  32. package/command-handler.js +0 -24
  33. package/command-handler.js.map +0 -1
  34. package/command-trigger.d.ts +0 -64
  35. package/command-trigger.d.ts.map +0 -1
  36. package/command-trigger.js +0 -64
  37. package/command-trigger.js.map +0 -1
  38. package/context-consumer.d.ts +0 -124
  39. package/context-consumer.d.ts.map +0 -1
  40. package/context-consumer.js +0 -124
  41. package/context-consumer.js.map +0 -1
  42. package/context-provider.d.ts +0 -120
  43. package/context-provider.d.ts.map +0 -1
  44. package/context-provider.js +0 -120
  45. package/context-provider.js.map +0 -1
  46. package/core.d.ts +0 -181
  47. package/core.d.ts.map +0 -1
  48. package/core.js +0 -388
  49. package/core.js.map +0 -1
  50. package/event-listener.d.ts +0 -120
  51. package/event-listener.d.ts.map +0 -1
  52. package/event-listener.js +0 -120
  53. package/event-listener.js.map +0 -1
  54. package/event-trigger.d.ts +0 -76
  55. package/event-trigger.d.ts.map +0 -1
  56. package/event-trigger.js +0 -76
  57. package/event-trigger.js.map +0 -1
  58. package/requestable-context-consumer.d.ts +0 -60
  59. package/requestable-context-consumer.d.ts.map +0 -1
  60. package/requestable-context-consumer.js +0 -54
  61. package/requestable-context-consumer.js.map +0 -1
  62. package/requestable-context-provider.d.ts +0 -69
  63. package/requestable-context-provider.d.ts.map +0 -1
  64. package/requestable-context-provider.js +0 -63
  65. package/requestable-context-provider.js.map +0 -1
package/core.js DELETED
@@ -1,388 +0,0 @@
1
- import { createLogger, globalAlwatr } from '@alwatr/logger';
2
- import { requestAnimationFrame } from '@alwatr/util';
3
- globalAlwatr.registeredList.push({
4
- name: '@alwatr/signal',
5
- version: _ALWATR_VERSION_,
6
- });
7
- /**
8
- * Listener `id`
9
- */
10
- let _lastListenerAutoId = 0;
11
- const debounceTimeout = 5;
12
- /**
13
- * Signal stack database.
14
- */
15
- const _signalStorage = {};
16
- export const logger = createLogger('alwatr/signal');
17
- /**
18
- * Get signal object by id, If not available, it will create a new signal with default options.
19
- *
20
- * Don't use it directly.
21
- *
22
- * Example:
23
- *
24
- * ```ts
25
- * const signal = getSignalObject<ContentType>('content-change');
26
- * signal.disabled = true;
27
- * ```
28
- */
29
- export const getSignalObject = (id) => {
30
- let signal = _signalStorage[id];
31
- if (signal == null) {
32
- signal = _signalStorage[id] = {
33
- id,
34
- disabled: false,
35
- debounced: false,
36
- listenerList: [],
37
- };
38
- }
39
- return signal;
40
- };
41
- /**
42
- * Call all listeners callback of special signal.
43
- *
44
- * Used inside dispatch, Don't use it directly.
45
- */
46
- export const _callListeners = (signal, detail) => {
47
- logger.logMethodArgs?.('_callListeners', { signalId: signal.id, signalDetail: detail });
48
- const removeList = [];
49
- for (const listener of signal.listenerList) {
50
- if (listener.disabled)
51
- continue;
52
- if (listener.once)
53
- removeList.push(listener);
54
- try {
55
- const ret = listener.callback(detail);
56
- if (ret instanceof Promise) {
57
- ret.catch((err) => logger.error('_callListeners', 'call_listener_failed', err, {
58
- signalId: signal.id,
59
- }));
60
- }
61
- }
62
- catch (err) {
63
- logger.error('_callListeners', 'call_listener_failed', err, {
64
- signalId: signal.id,
65
- });
66
- }
67
- }
68
- removeList.forEach((listener) => unsubscribe(listener));
69
- };
70
- /**
71
- * Subscribe new signal listener to a signal, work like addEventListener.
72
- *
73
- * Example:
74
- *
75
- * ```ts
76
- * const listener = subscribe<ContentType>('content-change', (content) => console.log(content));
77
- * // ...
78
- * unsubscribe(listener);
79
- * ```
80
- */
81
- export const subscribe = (signalId, listenerCallback, options = {}) => {
82
- options.once ?? (options.once = false);
83
- options.disabled ?? (options.disabled = false);
84
- options.receivePrevious ?? (options.receivePrevious = 'NextCycle');
85
- options.priority ?? (options.priority = false);
86
- logger.logMethodArgs?.('subscribe', { signalId, options });
87
- const signal = getSignalObject(signalId);
88
- const listener = {
89
- id: ++_lastListenerAutoId,
90
- signalId: signal.id,
91
- once: options.once,
92
- disabled: options.disabled,
93
- callback: listenerCallback,
94
- };
95
- const execCallback = signal.detail !== undefined && options.receivePrevious !== 'No' && options.disabled !== true;
96
- if (execCallback) {
97
- // Run callback for old dispatch signal
98
- const callback = () => {
99
- try {
100
- if (signal.detail !== undefined)
101
- listenerCallback(signal.detail);
102
- }
103
- catch (err) {
104
- logger.error('subscribe', 'call_signal_callback_failed', err, {
105
- signalId: signal.id,
106
- });
107
- }
108
- };
109
- if (options.receivePrevious === 'AnimationFrame') {
110
- requestAnimationFrame(callback);
111
- }
112
- else {
113
- setTimeout(callback, options.receivePrevious === 'NextCycle' ? 0 : debounceTimeout);
114
- }
115
- }
116
- // if once then must remove listener after fist callback called! then why push it to listenerList?!
117
- if (!(execCallback && options.once)) {
118
- if (options.priority === true) {
119
- signal.listenerList.unshift(listener);
120
- }
121
- else {
122
- signal.listenerList.push(listener);
123
- }
124
- }
125
- return {
126
- id: listener.id,
127
- signalId: listener.signalId,
128
- };
129
- };
130
- /**
131
- * Unsubscribe listener from signal, work like removeEventListener.
132
- *
133
- * Example:
134
- *
135
- * ```ts
136
- * const listener = subscribe<ContentType>('content-change', (content) => console.log(content));
137
- * // ...
138
- * unsubscribe(listener);
139
- * ```
140
- */
141
- export const unsubscribe = (listener) => {
142
- logger.logMethodArgs?.('unsubscribe', listener);
143
- const signal = getSignalObject(listener.signalId);
144
- const listenerIndex = signal.listenerList.findIndex((_listener) => _listener.id === listener.id);
145
- if (listenerIndex !== -1) {
146
- void signal.listenerList.splice(listenerIndex, 1);
147
- }
148
- };
149
- /**
150
- * Unsubscribe all listener from a signal, clear all listeners.
151
- *
152
- * Example:
153
- *
154
- * ```ts
155
- * removeAllListeners('content-change');
156
- * ```
157
- */
158
- export const removeAllListeners = (signalId) => {
159
- logger.logMethodArgs?.('removeAllListeners', signalId);
160
- const signal = getSignalObject(signalId);
161
- if (signal.listenerList.length === 0)
162
- return;
163
- signal.listenerList.length = 0;
164
- signal.listenerList = [];
165
- };
166
- /**
167
- * Dispatch (send) signal to all listeners.
168
- *
169
- * Signal detail changed immediately without any debounce.
170
- *
171
- * Example:
172
- *
173
- * ```ts
174
- * dispatch<ContentType>('content-change', newContent);
175
- * ```
176
- */
177
- export const dispatch = (signalId, detail, options = {}) => {
178
- options.debounce ?? (options.debounce = 'AnimationFrame');
179
- logger.logMethodArgs?.('dispatch', { signalId, detail, options });
180
- const signal = getSignalObject(signalId);
181
- // set detail before check signal.debounced for act like throttle (call listeners with last dispatch detail).
182
- signal.detail = detail;
183
- if (signal.disabled)
184
- return; // signal is disabled.
185
- if (options.debounce === 'No') {
186
- return _callListeners(signal, detail);
187
- }
188
- // else
189
- if (options.debounce === 'NextCycle') {
190
- setTimeout(_callListeners, 0, signal, detail);
191
- return;
192
- }
193
- // else
194
- if (signal.debounced === true) {
195
- return; // last dispatch in progress.
196
- }
197
- // else
198
- signal.debounced = true;
199
- const callListeners = () => {
200
- _callListeners(signal, signal.detail ?? detail);
201
- signal.debounced = false;
202
- };
203
- options.debounce === 'AnimationFrame'
204
- ? requestAnimationFrame(callListeners)
205
- : setTimeout(callListeners, debounceTimeout);
206
- };
207
- /**
208
- * Get current signal detail/value.
209
- *
210
- * Return undefined if signal not dispatched before or expired.
211
- *
212
- * Example:
213
- *
214
- * ```ts
215
- * const currentContent = getDetail<ContentType>('content-change');
216
- * if (currentContent === undefined) {
217
- * // signal not dispatched yet
218
- * }
219
- * ```
220
- */
221
- export const getDetail = (signalId) => {
222
- return getSignalObject(signalId).detail;
223
- };
224
- /**
225
- * Get the detail/value of the next received signal.
226
- *
227
- * Example:
228
- *
229
- * ```ts
230
- * const newContent = await untilNext<ContentType>('content-change');
231
- * ```
232
- */
233
- export const untilNext = (signalId) => {
234
- return new Promise((resolve) => {
235
- logger.logMethodArgs?.('untilNext', signalId);
236
- subscribe(signalId, resolve, {
237
- once: true,
238
- priority: true,
239
- receivePrevious: 'No',
240
- });
241
- });
242
- };
243
- /**
244
- * Defines the provider of the context signal that will be called when the context requested.
245
- * Subscribe to `request-signalId`.
246
- *
247
- * Example:
248
- *
249
- * ```ts
250
- * setContextProvider('content-change', async (requestParam) => await fetchNewContent(requestParam));
251
- * ```
252
- */
253
- export const setContextProvider = (signalId,
254
- // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
255
- signalProvider, options = {}) => {
256
- options.debounce ?? (options.debounce = 'AnimationFrame');
257
- options.receivePrevious ?? (options.receivePrevious = 'AnimationFrame');
258
- logger.logMethodArgs?.('setContextProvider', { signalId, options });
259
- const requestSignalId = 'request-' + signalId;
260
- removeAllListeners(requestSignalId);
261
- subscribe(requestSignalId, async (argumentObject) => {
262
- const signalDetail = await signalProvider(argumentObject);
263
- if (signalDetail !== undefined) {
264
- dispatch(signalId, signalDetail, { debounce: options.debounce });
265
- }
266
- }, {
267
- receivePrevious: options.receivePrevious,
268
- });
269
- };
270
- /**
271
- * Defines the command and dispatch returned value.
272
- *
273
- * Subscribe commandFunction to request-command-signal and dispatch callback-signal with commandFunction return value.
274
- *
275
- * Example:
276
- *
277
- * ```ts
278
- * defineCommand<TArgument, TReturn>(
279
- * 'show-prompt',
280
- * async (argumentObject) => {
281
- * return await showPrompt(argumentObject);
282
- * },
283
- * );
284
- * ```
285
- */
286
- export const defineCommand = (signalId, signalProvider, options = {}) => {
287
- options.debounce ?? (options.debounce = 'AnimationFrame');
288
- logger.logMethodArgs?.('defineCommand', { commandId: signalId, options });
289
- const requestSignalId = 'request-' + signalId;
290
- removeAllListeners(requestSignalId);
291
- return subscribe(requestSignalId, async (argumentObject) => {
292
- clearDetail(requestSignalId); // clean argumentObject from memory
293
- if (argumentObject._callbackSignalId == null) {
294
- signalProvider(argumentObject);
295
- }
296
- else {
297
- // prettier-ignore
298
- dispatch(argumentObject._callbackSignalId, await signalProvider(argumentObject), { debounce: options.debounce });
299
- }
300
- }, { receivePrevious: 'NextCycle' });
301
- };
302
- /**
303
- * Dispatch request context signal with requestParam as detail.
304
- *
305
- * Example:
306
- *
307
- * ```ts
308
- * requestContext<RequestParamType>('content-change', {foo: 'bar'});
309
- * const newContent = await untilNext<ContentType>('content-change');
310
- * ```
311
- */
312
- export const requestContext = (contextId, requestParam, options = {}) => {
313
- logger.logMethodArgs?.('requestContext', { contextId, requestParam });
314
- return dispatch(`request-${contextId}`, requestParam, options);
315
- };
316
- /**
317
- * Dispatch request command signal with commandArgument as detail.
318
- *
319
- * Example:
320
- *
321
- * ```ts
322
- * requestCommand<ArgumentType>('show-dialog', {foo: 'bar'});
323
- * ```
324
- */
325
- export const requestCommand = (commandId, commandArgument) => {
326
- logger.logMethodArgs?.('requestCommand', { commandId, commandArgument });
327
- dispatch(`request-${commandId}`, commandArgument, { debounce: 'No' });
328
- };
329
- /**
330
- * Dispatch request command signal with commandArgument as detail and return untilNext of callback signal.
331
- *
332
- * Request command and wait for answer.
333
- *
334
- * Example:
335
- *
336
- * ```ts
337
- * const response = await requestCommandWithResponse<ArgumentType, ReturnType>('show-dialog', {foo: 'bar'});
338
- * ```
339
- */
340
- export const requestCommandWithResponse = async (commandId, commandArgument) => {
341
- logger.logMethodArgs?.('requestCommand', { commandId, commandArgument });
342
- const _requestSignalId = `request-${commandId}`;
343
- const _callbackSignalId = `callback-${commandId}-${++_lastListenerAutoId}`;
344
- const untilCallback = untilNext(_callbackSignalId);
345
- dispatch(_requestSignalId, {
346
- ...commandArgument,
347
- _callbackSignalId,
348
- }, { debounce: 'NextCycle' });
349
- const response = await untilCallback;
350
- destroySignal(_callbackSignalId);
351
- return response;
352
- };
353
- /**
354
- * Clear current signal detail without dispatch new signal.
355
- *
356
- * new subscriber options.receivePrevious not work until new signal
357
- *
358
- * Example:
359
- *
360
- * ```ts
361
- * clearDetail('product-list');
362
- * ```
363
- */
364
- export const clearDetail = (signalId) => {
365
- logger.logMethodArgs?.('expire', signalId);
366
- const signal = getSignalObject(signalId);
367
- delete signal.detail;
368
- };
369
- /**
370
- * Delete signal object with detail and listeners and options.
371
- *
372
- * new subscriber options.receivePrevious not work until new signal
373
- *
374
- * Example:
375
- *
376
- * ```ts
377
- * destroySignal('product-list');
378
- * ```
379
- */
380
- export const destroySignal = (signalId) => {
381
- logger.logMethodArgs?.('destroySignal', signalId);
382
- const signal = _signalStorage[signalId];
383
- if (signal == null)
384
- return;
385
- signal.listenerList.length = 0;
386
- delete _signalStorage[signalId];
387
- };
388
- //# sourceMappingURL=core.js.map
package/core.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"core.js","sourceRoot":"","sources":["src/core.ts"],"names":[],"mappings":"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","sourcesContent":["import {createLogger, globalAlwatr} from '@alwatr/logger';\nimport {requestAnimationFrame} from '@alwatr/util';\n\nimport type {\n DispatchOptions,\n ListenerFunction,\n ListenerObject,\n SubscribeOptions,\n SignalObject,\n ProviderFunction,\n ProviderOptions,\n SignalStorage,\n ListenerSpec,\n} from './type.js';\nimport type {Stringifyable, StringifyableRecord} from '@alwatr/type';\n\nglobalAlwatr.registeredList.push({\n name: '@alwatr/signal',\n version: _ALWATR_VERSION_,\n});\n\n/**\n * Listener `id`\n */\nlet _lastListenerAutoId = 0;\n\nconst debounceTimeout = 5;\n\n/**\n * Signal stack database.\n */\nconst _signalStorage: SignalStorage = {};\n\nexport const logger = createLogger('alwatr/signal');\n\n/**\n * Get signal object by id, If not available, it will create a new signal with default options.\n *\n * Don't use it directly.\n *\n * Example:\n *\n * ```ts\n * const signal = getSignalObject<ContentType>('content-change');\n * signal.disabled = true;\n * ```\n */\nexport const getSignalObject = <T extends Stringifyable>(id: string): SignalObject<T> => {\n let signal = _signalStorage[id] as SignalObject<T> | undefined;\n if (signal == null) {\n signal = _signalStorage[id] = {\n id,\n disabled: false,\n debounced: false,\n listenerList: [],\n };\n }\n return signal;\n};\n\n/**\n * Call all listeners callback of special signal.\n *\n * Used inside dispatch, Don't use it directly.\n */\nexport const _callListeners = <T extends Stringifyable>(signal: SignalObject<T>, detail: T): void => {\n logger.logMethodArgs?.('_callListeners', {signalId: signal.id, signalDetail: detail});\n\n const removeList: ListenerObject<T>[] = [];\n\n for (const listener of signal.listenerList) {\n if (listener.disabled) continue;\n if (listener.once) removeList.push(listener);\n try {\n const ret = listener.callback(detail);\n if (ret instanceof Promise) {\n ret.catch((err) =>\n logger.error('_callListeners', 'call_listener_failed', err, {\n signalId: signal.id,\n }),\n );\n }\n }\n catch (err) {\n logger.error('_callListeners', 'call_listener_failed', err, {\n signalId: signal.id,\n });\n }\n }\n\n removeList.forEach((listener) => unsubscribe(listener));\n};\n\n/**\n * Subscribe new signal listener to a signal, work like addEventListener.\n *\n * Example:\n *\n * ```ts\n * const listener = subscribe<ContentType>('content-change', (content) => console.log(content));\n * // ...\n * unsubscribe(listener);\n * ```\n */\nexport const subscribe = <T extends Stringifyable>(\n signalId: string,\n listenerCallback: ListenerFunction<T>,\n options: Partial<SubscribeOptions> = {},\n): ListenerSpec => {\n options.once ??= false;\n options.disabled ??= false;\n options.receivePrevious ??= 'NextCycle';\n options.priority ??= false;\n\n logger.logMethodArgs?.('subscribe', {signalId, options});\n\n const signal = getSignalObject<T>(signalId);\n\n const listener: ListenerObject<T> = {\n id: ++_lastListenerAutoId,\n signalId: signal.id,\n once: options.once,\n disabled: options.disabled,\n callback: listenerCallback,\n };\n\n const execCallback = signal.detail !== undefined && options.receivePrevious !== 'No' && options.disabled !== true;\n if (execCallback) {\n // Run callback for old dispatch signal\n\n const callback = (): void => {\n try {\n if (signal.detail !== undefined) listenerCallback(signal.detail);\n }\n catch (err) {\n logger.error('subscribe', 'call_signal_callback_failed', err, {\n signalId: signal.id,\n });\n }\n };\n\n if (options.receivePrevious === 'AnimationFrame') {\n requestAnimationFrame(callback);\n }\n else {\n setTimeout(callback, options.receivePrevious === 'NextCycle' ? 0 : debounceTimeout);\n }\n }\n\n // if once then must remove listener after fist callback called! then why push it to listenerList?!\n if (!(execCallback && options.once)) {\n if (options.priority === true) {\n signal.listenerList.unshift(listener);\n }\n else {\n signal.listenerList.push(listener);\n }\n }\n\n return {\n id: listener.id,\n signalId: listener.signalId,\n };\n};\n\n/**\n * Unsubscribe listener from signal, work like removeEventListener.\n *\n * Example:\n *\n * ```ts\n * const listener = subscribe<ContentType>('content-change', (content) => console.log(content));\n * // ...\n * unsubscribe(listener);\n * ```\n */\nexport const unsubscribe = (listener: ListenerSpec): void => {\n logger.logMethodArgs?.('unsubscribe', listener);\n const signal = getSignalObject(listener.signalId);\n const listenerIndex = signal.listenerList.findIndex((_listener) => _listener.id === listener.id);\n if (listenerIndex !== -1) {\n void signal.listenerList.splice(listenerIndex, 1);\n }\n};\n\n/**\n * Unsubscribe all listener from a signal, clear all listeners.\n *\n * Example:\n *\n * ```ts\n * removeAllListeners('content-change');\n * ```\n */\nexport const removeAllListeners = (signalId: string): void => {\n logger.logMethodArgs?.('removeAllListeners', signalId);\n const signal = getSignalObject(signalId);\n if (signal.listenerList.length === 0) return;\n signal.listenerList.length = 0;\n signal.listenerList = [];\n};\n\n/**\n * Dispatch (send) signal to all listeners.\n *\n * Signal detail changed immediately without any debounce.\n *\n * Example:\n *\n * ```ts\n * dispatch<ContentType>('content-change', newContent);\n * ```\n */\nexport const dispatch = <T extends Stringifyable>(\n signalId: string,\n detail: T,\n options: Partial<DispatchOptions> = {},\n): void => {\n options.debounce ??= 'AnimationFrame';\n\n logger.logMethodArgs?.('dispatch', {signalId, detail, options});\n\n const signal = getSignalObject<T>(signalId);\n\n // set detail before check signal.debounced for act like throttle (call listeners with last dispatch detail).\n signal.detail = detail;\n\n if (signal.disabled) return; // signal is disabled.\n\n if (options.debounce === 'No') {\n return _callListeners(signal, detail);\n }\n\n // else\n if (options.debounce === 'NextCycle') {\n setTimeout(_callListeners, 0, signal, detail);\n return;\n }\n\n // else\n if (signal.debounced === true) {\n return; // last dispatch in progress.\n }\n\n // else\n signal.debounced = true;\n const callListeners = (): void => {\n _callListeners(signal, signal.detail ?? detail);\n signal.debounced = false;\n };\n options.debounce === 'AnimationFrame'\n ? requestAnimationFrame(callListeners)\n : setTimeout(callListeners, debounceTimeout);\n};\n\n/**\n * Get current signal detail/value.\n *\n * Return undefined if signal not dispatched before or expired.\n *\n * Example:\n *\n * ```ts\n * const currentContent = getDetail<ContentType>('content-change');\n * if (currentContent === undefined) {\n * // signal not dispatched yet\n * }\n * ```\n */\nexport const getDetail = <T extends Stringifyable>(signalId: string): T | undefined => {\n return getSignalObject<T>(signalId).detail;\n};\n\n/**\n * Get the detail/value of the next received signal.\n *\n * Example:\n *\n * ```ts\n * const newContent = await untilNext<ContentType>('content-change');\n * ```\n */\nexport const untilNext = <T extends Stringifyable>(signalId: string): Promise<T> => {\n return new Promise((resolve) => {\n logger.logMethodArgs?.('untilNext', signalId);\n subscribe<T>(signalId, resolve, {\n once: true,\n priority: true,\n receivePrevious: 'No',\n });\n });\n};\n\n/**\n * Defines the provider of the context signal that will be called when the context requested.\n * Subscribe to `request-signalId`.\n *\n * Example:\n *\n * ```ts\n * setContextProvider('content-change', async (requestParam) => await fetchNewContent(requestParam));\n * ```\n */\nexport const setContextProvider = <TContext extends Stringifyable, TRquest extends Stringifyable = null>(\n signalId: string,\n // eslint-disable-next-line @typescript-eslint/no-invalid-void-type\n signalProvider: ProviderFunction<TRquest, TContext | void>,\n options: Partial<ProviderOptions> = {},\n): void => {\n options.debounce ??= 'AnimationFrame';\n options.receivePrevious ??= 'AnimationFrame';\n logger.logMethodArgs?.('setContextProvider', {signalId, options});\n const requestSignalId = 'request-' + signalId;\n removeAllListeners(requestSignalId);\n subscribe<TRquest>(\n requestSignalId,\n async (argumentObject): Promise<void> => {\n const signalDetail = await signalProvider(argumentObject);\n if (signalDetail !== undefined) {\n dispatch<TContext>(signalId, signalDetail, {debounce: options.debounce});\n }\n },\n {\n receivePrevious: options.receivePrevious,\n },\n );\n};\n\n/**\n * Defines the command and dispatch returned value.\n *\n * Subscribe commandFunction to request-command-signal and dispatch callback-signal with commandFunction return value.\n *\n * Example:\n *\n * ```ts\n * defineCommand<TArgument, TReturn>(\n * 'show-prompt',\n * async (argumentObject) => {\n * return await showPrompt(argumentObject);\n * },\n * );\n * ```\n */\nexport const defineCommand = <TArgument extends StringifyableRecord, TReturn extends Stringifyable>(\n signalId: string,\n signalProvider: ProviderFunction<TArgument & {_callbackSignalId?: string}, TReturn>,\n options: Partial<Pick<ProviderOptions, 'debounce'>> = {},\n): ListenerSpec => {\n options.debounce ??= 'AnimationFrame';\n logger.logMethodArgs?.('defineCommand', {commandId: signalId, options});\n const requestSignalId = 'request-' + signalId;\n removeAllListeners(requestSignalId);\n return subscribe<TArgument & {_callbackSignalId?: string}>(\n requestSignalId,\n async (argumentObject) => {\n clearDetail(requestSignalId); // clean argumentObject from memory\n if (argumentObject._callbackSignalId == null) {\n signalProvider(argumentObject);\n }\n else {\n // prettier-ignore\n dispatch<TReturn>(\n argumentObject._callbackSignalId,\n await signalProvider(argumentObject),\n {debounce: options.debounce},\n );\n }\n },\n {receivePrevious: 'NextCycle'},\n );\n};\n\n/**\n * Dispatch request context signal with requestParam as detail.\n *\n * Example:\n *\n * ```ts\n * requestContext<RequestParamType>('content-change', {foo: 'bar'});\n * const newContent = await untilNext<ContentType>('content-change');\n * ```\n */\nexport const requestContext = <TRequest extends Stringifyable>(\n contextId: string,\n requestParam: TRequest,\n options: Partial<DispatchOptions> = {},\n): void => {\n logger.logMethodArgs?.('requestContext', {contextId, requestParam});\n return dispatch<TRequest>(`request-${contextId}`, requestParam, options);\n};\n\n/**\n * Dispatch request command signal with commandArgument as detail.\n *\n * Example:\n *\n * ```ts\n * requestCommand<ArgumentType>('show-dialog', {foo: 'bar'});\n * ```\n */\nexport const requestCommand = <TArgument extends StringifyableRecord>(\n commandId: string,\n commandArgument: TArgument,\n): void => {\n logger.logMethodArgs?.('requestCommand', {commandId, commandArgument});\n dispatch<TArgument>(`request-${commandId}`, commandArgument, {debounce: 'No'});\n};\n\n/**\n * Dispatch request command signal with commandArgument as detail and return untilNext of callback signal.\n *\n * Request command and wait for answer.\n *\n * Example:\n *\n * ```ts\n * const response = await requestCommandWithResponse<ArgumentType, ReturnType>('show-dialog', {foo: 'bar'});\n * ```\n */\nexport const requestCommandWithResponse = async <\n TArgument extends StringifyableRecord,\n TReturn extends Stringifyable\n>(\n commandId: string,\n commandArgument: TArgument,\n): Promise<TReturn> => {\n logger.logMethodArgs?.('requestCommand', {commandId, commandArgument});\n\n const _requestSignalId = `request-${commandId}`;\n const _callbackSignalId = `callback-${commandId}-${++_lastListenerAutoId}`;\n const untilCallback = untilNext<TReturn>(_callbackSignalId);\n\n dispatch<TArgument & {_callbackSignalId: string}>(\n _requestSignalId,\n {\n ...commandArgument,\n _callbackSignalId,\n },\n {debounce: 'NextCycle'},\n );\n\n const response = await untilCallback;\n destroySignal(_callbackSignalId);\n return response;\n};\n\n/**\n * Clear current signal detail without dispatch new signal.\n *\n * new subscriber options.receivePrevious not work until new signal\n *\n * Example:\n *\n * ```ts\n * clearDetail('product-list');\n * ```\n */\nexport const clearDetail = (signalId: string): void => {\n logger.logMethodArgs?.('expire', signalId);\n const signal = getSignalObject(signalId);\n delete signal.detail;\n};\n\n/**\n * Delete signal object with detail and listeners and options.\n *\n * new subscriber options.receivePrevious not work until new signal\n *\n * Example:\n *\n * ```ts\n * destroySignal('product-list');\n * ```\n */\nexport const destroySignal = (signalId: string): void => {\n logger.logMethodArgs?.('destroySignal', signalId);\n const signal = _signalStorage[signalId];\n if (signal == null) return;\n signal.listenerList.length = 0;\n delete _signalStorage[signalId];\n};\n"]}
@@ -1,120 +0,0 @@
1
- import type { Stringifyable } from '@alwatr/type';
2
- /**
3
- * Event signal listener/subscriber interface.
4
- */
5
- export declare const eventListener: {
6
- /**
7
- * Get last event dispatched detail.
8
- *
9
- * Return undefined if signal not dispatched before or expired.
10
- *
11
- * Example:
12
- *
13
- * ```ts
14
- * const currentSize = eventTrigger.getLastDetail<ResizeType>('window-resize');
15
- * if (currentSize === undefined) {
16
- * // event-signal not dispatched yet
17
- * }
18
- * ```
19
- */
20
- readonly getLastDetail: <T extends Stringifyable>(signalId: string) => T | undefined;
21
- /**
22
- * Wait until new event.
23
- *
24
- * Example:
25
- *
26
- * ```ts
27
- * const newSize = await eventTrigger.untilNext<ResizeType>('window-resize');
28
- * ```
29
- */
30
- readonly untilNext: <T_1 extends Stringifyable>(signalId: string) => Promise<T_1>;
31
- /**
32
- * Subscribe new listener to an event, work like addEventListener.
33
- *
34
- * Example:
35
- *
36
- * ```ts
37
- * const listener = eventTrigger.subscribe<ResizeType>('window-resize', (size) => console.log(size));
38
- * // ...
39
- * eventTrigger.unsubscribe(listener);
40
- * ```
41
- */
42
- readonly subscribe: <T_2 extends Stringifyable>(signalId: string, listenerCallback: import("./type.js").ListenerFunction<T_2>, options?: Partial<import("./type.js").SubscribeOptions>) => import("./type.js").ListenerSpec;
43
- /**
44
- * Unsubscribe listener from event, work like removeEventListener.
45
- *
46
- * Example:
47
- *
48
- * ```ts
49
- * const listener = eventTrigger.subscribe<ResizeType>('window-resize', (size) => console.log(size));
50
- * // ...
51
- * eventTrigger.unsubscribe(listener);
52
- * ```
53
- */
54
- readonly unsubscribe: (listener: import("./type.js").ListenerSpec) => void;
55
- /**
56
- * Bind this interface to special event.
57
- *
58
- * Example:
59
- *
60
- * ```ts
61
- * const resizeEvent = eventTrigger.bind<ResizeType>('window-resize');
62
- * ```
63
- */
64
- readonly bind: <T_3 extends Stringifyable>(eventId: string) => {
65
- /**
66
- * Event signal Id.
67
- */
68
- readonly id: string;
69
- /**
70
- * Get last event dispatched detail.
71
- *
72
- * Return undefined if signal not dispatched before or expired.
73
- *
74
- * Example:
75
- *
76
- * ```ts
77
- * const currentSize = resizeEvent.getLastDetail();
78
- * if (currentSize === undefined) {
79
- * // signal not dispatched yet
80
- * }
81
- * ```
82
- */
83
- readonly getLastDetail: () => T_3 | undefined;
84
- /**
85
- * Wait until new event.
86
- *
87
- * Example:
88
- *
89
- * ```ts
90
- * const newSize = await resizeEvent.untilNext();
91
- * ```
92
- */
93
- readonly untilNext: () => Promise<T_3>;
94
- /**
95
- * Subscribe new listener to an event, work like addEventListener.
96
- *
97
- * Example:
98
- *
99
- * ```ts
100
- * const listener = resizeEvent.subscribe((size) => console.log(size));
101
- * // ...
102
- * resizeEvent.unsubscribe(listener);
103
- * ```
104
- */
105
- readonly subscribe: (listenerCallback: import("./type.js").ListenerFunction<T_3>, options?: Partial<import("./type.js").SubscribeOptions> | undefined) => import("./type.js").ListenerSpec;
106
- /**
107
- * Unsubscribe listener from event, work like removeEventListener.
108
- *
109
- * Example:
110
- *
111
- * ```ts
112
- * const listener = resizeEvent.subscribe((size) => console.log(size));
113
- * // ...
114
- * resizeEvent.unsubscribe(listener);
115
- * ```
116
- */
117
- readonly unsubscribe: (listener: import("./type.js").ListenerSpec) => void;
118
- };
119
- };
120
- //# sourceMappingURL=event-listener.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"event-listener.d.ts","sourceRoot":"","sources":["src/event-listener.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,aAAa,EAAiB,MAAM,cAAc,CAAC;AAEhE;;GAEG;AACH,eAAO,MAAM,aAAa;IACxB;;;;;;;;;;;;;OAaG;;IAGH;;;;;;;;OAQG;;IAGH;;;;;;;;;;OAUG;;IAGH;;;;;;;;;;OAUG;;IAGH;;;;;;;;OAQG;wDACsC,MAAM;QAC7C;;WAEG;;QAGH;;;;;;;;;;;;;WAaG;;QAGH;;;;;;;;WAQG;;QAGH;;;;;;;;;;WAUG;;QAIH;;;;;;;;;;WAUG;;;CAGG,CAAC"}
package/event-listener.js DELETED
@@ -1,120 +0,0 @@
1
- import { getDetail, subscribe, unsubscribe, untilNext } from './core.js';
2
- /**
3
- * Event signal listener/subscriber interface.
4
- */
5
- export const eventListener = {
6
- /**
7
- * Get last event dispatched detail.
8
- *
9
- * Return undefined if signal not dispatched before or expired.
10
- *
11
- * Example:
12
- *
13
- * ```ts
14
- * const currentSize = eventTrigger.getLastDetail<ResizeType>('window-resize');
15
- * if (currentSize === undefined) {
16
- * // event-signal not dispatched yet
17
- * }
18
- * ```
19
- */
20
- getLastDetail: getDetail,
21
- /**
22
- * Wait until new event.
23
- *
24
- * Example:
25
- *
26
- * ```ts
27
- * const newSize = await eventTrigger.untilNext<ResizeType>('window-resize');
28
- * ```
29
- */
30
- untilNext: untilNext,
31
- /**
32
- * Subscribe new listener to an event, work like addEventListener.
33
- *
34
- * Example:
35
- *
36
- * ```ts
37
- * const listener = eventTrigger.subscribe<ResizeType>('window-resize', (size) => console.log(size));
38
- * // ...
39
- * eventTrigger.unsubscribe(listener);
40
- * ```
41
- */
42
- subscribe: subscribe,
43
- /**
44
- * Unsubscribe listener from event, work like removeEventListener.
45
- *
46
- * Example:
47
- *
48
- * ```ts
49
- * const listener = eventTrigger.subscribe<ResizeType>('window-resize', (size) => console.log(size));
50
- * // ...
51
- * eventTrigger.unsubscribe(listener);
52
- * ```
53
- */
54
- unsubscribe: unsubscribe,
55
- /**
56
- * Bind this interface to special event.
57
- *
58
- * Example:
59
- *
60
- * ```ts
61
- * const resizeEvent = eventTrigger.bind<ResizeType>('window-resize');
62
- * ```
63
- */
64
- bind: (eventId) => ({
65
- /**
66
- * Event signal Id.
67
- */
68
- id: eventId,
69
- /**
70
- * Get last event dispatched detail.
71
- *
72
- * Return undefined if signal not dispatched before or expired.
73
- *
74
- * Example:
75
- *
76
- * ```ts
77
- * const currentSize = resizeEvent.getLastDetail();
78
- * if (currentSize === undefined) {
79
- * // signal not dispatched yet
80
- * }
81
- * ```
82
- */
83
- getLastDetail: getDetail.bind(null, eventId),
84
- /**
85
- * Wait until new event.
86
- *
87
- * Example:
88
- *
89
- * ```ts
90
- * const newSize = await resizeEvent.untilNext();
91
- * ```
92
- */
93
- untilNext: untilNext.bind(null, eventId),
94
- /**
95
- * Subscribe new listener to an event, work like addEventListener.
96
- *
97
- * Example:
98
- *
99
- * ```ts
100
- * const listener = resizeEvent.subscribe((size) => console.log(size));
101
- * // ...
102
- * resizeEvent.unsubscribe(listener);
103
- * ```
104
- */
105
- subscribe: subscribe.bind(null, eventId),
106
- /**
107
- * Unsubscribe listener from event, work like removeEventListener.
108
- *
109
- * Example:
110
- *
111
- * ```ts
112
- * const listener = resizeEvent.subscribe((size) => console.log(size));
113
- * // ...
114
- * resizeEvent.unsubscribe(listener);
115
- * ```
116
- */
117
- unsubscribe: unsubscribe,
118
- }),
119
- };
120
- //# sourceMappingURL=event-listener.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"event-listener.js","sourceRoot":"","sources":["src/event-listener.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAC,MAAM,WAAW,CAAC;AAIvE;;GAEG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B;;;;;;;;;;;;;OAaG;IACH,aAAa,EAAE,SAAS;IAExB;;;;;;;;OAQG;IACH,SAAS,EAAE,SAAS;IAEpB;;;;;;;;;;OAUG;IACH,SAAS,EAAE,SAAS;IAEpB;;;;;;;;;;OAUG;IACH,WAAW,EAAE,WAAW;IAExB;;;;;;;;OAQG;IACH,IAAI,EAAE,CAA0B,OAAe,EAAE,EAAE,CAAC,CAAC;QACnD;;WAEG;QACH,EAAE,EAAE,OAAO;QAEX;;;;;;;;;;;;;WAaG;QACH,aAAa,EAAE,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAwC;QAEnF;;;;;;;;WAQG;QACH,SAAS,EAAE,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAwC;QAE/E;;;;;;;;;;WAUG;QACH,SAAS,EAAE,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CACF;QAErC;;;;;;;;;;WAUG;QACH,WAAW,EAAE,WAAW;KACf,CAAA;CACH,CAAC","sourcesContent":["import {getDetail, subscribe, unsubscribe, untilNext} from './core.js';\n\nimport type {Stringifyable, OmitFirstParam} from '@alwatr/type';\n\n/**\n * Event signal listener/subscriber interface.\n */\nexport const eventListener = {\n /**\n * Get last event dispatched detail.\n *\n * Return undefined if signal not dispatched before or expired.\n *\n * Example:\n *\n * ```ts\n * const currentSize = eventTrigger.getLastDetail<ResizeType>('window-resize');\n * if (currentSize === undefined) {\n * // event-signal not dispatched yet\n * }\n * ```\n */\n getLastDetail: getDetail,\n\n /**\n * Wait until new event.\n *\n * Example:\n *\n * ```ts\n * const newSize = await eventTrigger.untilNext<ResizeType>('window-resize');\n * ```\n */\n untilNext: untilNext,\n\n /**\n * Subscribe new listener to an event, work like addEventListener.\n *\n * Example:\n *\n * ```ts\n * const listener = eventTrigger.subscribe<ResizeType>('window-resize', (size) => console.log(size));\n * // ...\n * eventTrigger.unsubscribe(listener);\n * ```\n */\n subscribe: subscribe,\n\n /**\n * Unsubscribe listener from event, work like removeEventListener.\n *\n * Example:\n *\n * ```ts\n * const listener = eventTrigger.subscribe<ResizeType>('window-resize', (size) => console.log(size));\n * // ...\n * eventTrigger.unsubscribe(listener);\n * ```\n */\n unsubscribe: unsubscribe,\n\n /**\n * Bind this interface to special event.\n *\n * Example:\n *\n * ```ts\n * const resizeEvent = eventTrigger.bind<ResizeType>('window-resize');\n * ```\n */\n bind: <T extends Stringifyable>(eventId: string) => ({\n /**\n * Event signal Id.\n */\n id: eventId,\n\n /**\n * Get last event dispatched detail.\n *\n * Return undefined if signal not dispatched before or expired.\n *\n * Example:\n *\n * ```ts\n * const currentSize = resizeEvent.getLastDetail();\n * if (currentSize === undefined) {\n * // signal not dispatched yet\n * }\n * ```\n */\n getLastDetail: getDetail.bind(null, eventId) as OmitFirstParam<typeof getDetail<T>>,\n\n /**\n * Wait until new event.\n *\n * Example:\n *\n * ```ts\n * const newSize = await resizeEvent.untilNext();\n * ```\n */\n untilNext: untilNext.bind(null, eventId) as OmitFirstParam<typeof untilNext<T>>,\n\n /**\n * Subscribe new listener to an event, work like addEventListener.\n *\n * Example:\n *\n * ```ts\n * const listener = resizeEvent.subscribe((size) => console.log(size));\n * // ...\n * resizeEvent.unsubscribe(listener);\n * ```\n */\n subscribe: subscribe.bind(null, eventId) as unknown as\n OmitFirstParam<typeof subscribe<T>>,\n\n /**\n * Unsubscribe listener from event, work like removeEventListener.\n *\n * Example:\n *\n * ```ts\n * const listener = resizeEvent.subscribe((size) => console.log(size));\n * // ...\n * resizeEvent.unsubscribe(listener);\n * ```\n */\n unsubscribe: unsubscribe,\n } as const),\n} as const;\n"]}