@ms-cloudpack/data-bus 0.0.2 → 0.1.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.json +46 -1
  2. package/CHANGELOG.md +10 -2
  3. package/README.md +1 -1
  4. package/lib/addProvider.d.ts +5 -0
  5. package/lib/addProvider.js +10 -0
  6. package/lib/addProvider.js.map +1 -0
  7. package/lib/addProvider.test.d.ts +1 -0
  8. package/lib/addProvider.test.js +58 -0
  9. package/lib/addProvider.test.js.map +1 -0
  10. package/lib/createDataBus.d.ts +5 -0
  11. package/lib/createDataBus.js +23 -0
  12. package/lib/createDataBus.js.map +1 -0
  13. package/lib/createDataBus.test.d.ts +1 -0
  14. package/lib/createDataBus.test.js +26 -0
  15. package/lib/createDataBus.test.js.map +1 -0
  16. package/lib/createNode.d.ts +2 -0
  17. package/lib/createNode.js +6 -0
  18. package/lib/createNode.js.map +1 -0
  19. package/lib/getData.d.ts +5 -0
  20. package/lib/getData.js +9 -0
  21. package/lib/getData.js.map +1 -0
  22. package/lib/getData.test.d.ts +1 -0
  23. package/lib/getData.test.js +33 -0
  24. package/lib/getData.test.js.map +1 -0
  25. package/lib/getNode.d.ts +9 -0
  26. package/lib/getNode.js +20 -0
  27. package/lib/getNode.js.map +1 -0
  28. package/lib/getNode.test.d.ts +1 -0
  29. package/lib/getNode.test.js +42 -0
  30. package/lib/getNode.test.js.map +1 -0
  31. package/lib/index.d.ts +2 -0
  32. package/lib/index.js +2 -0
  33. package/lib/index.js.map +1 -0
  34. package/lib/publish.d.ts +5 -0
  35. package/lib/publish.js +23 -0
  36. package/lib/publish.js.map +1 -0
  37. package/lib/publish.test.d.ts +1 -0
  38. package/lib/publish.test.js +25 -0
  39. package/lib/publish.test.js.map +1 -0
  40. package/lib/subscribe.d.ts +2 -0
  41. package/lib/subscribe.js +44 -0
  42. package/lib/subscribe.js.map +1 -0
  43. package/lib/subscribe.test.d.ts +1 -0
  44. package/lib/subscribe.test.js +66 -0
  45. package/lib/subscribe.test.js.map +1 -0
  46. package/lib/tsdoc-metadata.json +11 -0
  47. package/lib/types.d.ts +39 -0
  48. package/lib/types.js +2 -0
  49. package/lib/types.js.map +1 -0
  50. package/package.json +12 -8
package/CHANGELOG.json CHANGED
@@ -2,7 +2,52 @@
2
2
  "name": "@ms-cloudpack/data-bus",
3
3
  "entries": [
4
4
  {
5
- "date": "Mon, 09 May 2022 18:54:32 GMT",
5
+ "date": "Fri, 12 Aug 2022 08:12:22 GMT",
6
+ "tag": "@ms-cloudpack/data-bus_v0.1.0",
7
+ "version": "0.1.0",
8
+ "comments": {
9
+ "minor": [
10
+ {
11
+ "author": "dzearing@microsoft.com",
12
+ "package": "@ms-cloudpack/data-bus",
13
+ "commit": "e733241cb555d1ae14cdfd8fe211d1d05b471e29",
14
+ "comment": "Providers can now be added to the root of the data tree."
15
+ }
16
+ ]
17
+ }
18
+ },
19
+ {
20
+ "date": "Fri, 20 May 2022 04:26:15 GMT",
21
+ "tag": "@ms-cloudpack/data-bus_v0.0.2",
22
+ "version": "0.0.2",
23
+ "comments": {
24
+ "none": [
25
+ {
26
+ "author": "dzearing@microsoft.com",
27
+ "package": "@ms-cloudpack/data-bus",
28
+ "commit": "b39bb143fc53e622c39f9e9fd349f71c9ebadd77",
29
+ "comment": "Adding api:update script."
30
+ }
31
+ ]
32
+ }
33
+ },
34
+ {
35
+ "date": "Sat, 14 May 2022 04:36:11 GMT",
36
+ "tag": "@ms-cloudpack/data-bus_v0.0.2",
37
+ "version": "0.0.2",
38
+ "comments": {
39
+ "none": [
40
+ {
41
+ "author": "dzearing@microsoft.com",
42
+ "package": "@ms-cloudpack/data-bus",
43
+ "commit": "cc0844a7d18790d69e59b16dbd6eef8fab5bc4e0",
44
+ "comment": "Updating package details."
45
+ }
46
+ ]
47
+ }
48
+ },
49
+ {
50
+ "date": "Mon, 09 May 2022 18:54:56 GMT",
6
51
  "tag": "@ms-cloudpack/data-bus_v0.0.2",
7
52
  "version": "0.0.2",
8
53
  "comments": {
package/CHANGELOG.md CHANGED
@@ -1,12 +1,20 @@
1
1
  # Change Log - @ms-cloudpack/data-bus
2
2
 
3
- This log was last generated on Mon, 09 May 2022 18:54:32 GMT and should not be manually modified.
3
+ This log was last generated on Fri, 12 Aug 2022 08:12:22 GMT and should not be manually modified.
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
+ ## 0.1.0
8
+
9
+ Fri, 12 Aug 2022 08:12:22 GMT
10
+
11
+ ### Minor changes
12
+
13
+ - Providers can now be added to the root of the data tree. (dzearing@microsoft.com)
14
+
7
15
  ## 0.0.2
8
16
 
9
- Mon, 09 May 2022 18:54:32 GMT
17
+ Mon, 09 May 2022 18:54:56 GMT
10
18
 
11
19
  ### Patches
12
20
 
package/README.md CHANGED
@@ -28,7 +28,7 @@ export const bus = createDataBus();
28
28
  ### Subscribing to data
29
29
 
30
30
  The data bus provides a method `subscribe` for consumers to subscribe to different types of data. As that data changes, consumers will be notified of changes. Any number of consumers can subscribe for the same data. Data is
31
- heirarchical, so you can subscribe to a full branch, or to a leaf node within the tree. Paths are represented by
31
+ hierarchical, so you can subscribe to a full branch, or to a leaf node within the tree. Paths are represented by
32
32
  string arrays.
33
33
 
34
34
  ```js
@@ -0,0 +1,5 @@
1
+ import type { DataBusState, DataBusProvider } from './types.js';
2
+ /**
3
+ * Adds a provider.
4
+ */
5
+ export declare function addProvider(state: DataBusState, provider: DataBusProvider): void;
@@ -0,0 +1,10 @@
1
+ import { getNode } from './getNode.js';
2
+ /**
3
+ * Adds a provider.
4
+ */
5
+ export function addProvider(state, provider) {
6
+ const { node } = getNode(state, provider.path, true);
7
+ node.providers ?? (node.providers = []);
8
+ node.providers.push(provider);
9
+ }
10
+ //# sourceMappingURL=addProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"addProvider.js","sourceRoot":"","sources":["../src/addProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,KAAmB,EAAE,QAAyB;IACxE,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAErD,IAAI,CAAC,SAAS,KAAd,IAAI,CAAC,SAAS,GAAK,EAAE,EAAC;IACtB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAChC,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,58 @@
1
+ import { jest } from '@jest/globals';
2
+ import { addProvider } from './addProvider.js';
3
+ import { publish } from './publish.js';
4
+ import { subscribe } from './subscribe.js';
5
+ import { createDataBus } from './createDataBus.js';
6
+ const testBus = createDataBus();
7
+ function getTestProvider(path) {
8
+ return {
9
+ path,
10
+ onActivate: jest.fn(),
11
+ onDeactivate: jest.fn(),
12
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
13
+ onPublish: jest.fn(),
14
+ };
15
+ }
16
+ describe('addProvider', () => {
17
+ it('can add a provider', () => {
18
+ const state = { root: {} };
19
+ const provider = getTestProvider(['a']);
20
+ addProvider(state, provider);
21
+ expect(state.root.children?.['a']?.providers).toContain(provider);
22
+ });
23
+ it('can have onActivate executed when a path is subscribed', () => {
24
+ const state = { root: {} };
25
+ const provider = getTestProvider(['a']);
26
+ const changeFn = jest.fn();
27
+ addProvider(state, provider);
28
+ subscribe(state, testBus, ['a'], changeFn);
29
+ expect(provider.onActivate).toBeCalledTimes(1);
30
+ subscribe(state, testBus, ['a'], changeFn);
31
+ expect(provider.onActivate).toBeCalledTimes(1);
32
+ expect(changeFn).not.toBeCalled();
33
+ });
34
+ it('can have onDeactivate executed when a path is unsubscribed', () => {
35
+ const state = { root: {} };
36
+ const provider = getTestProvider(['a']);
37
+ addProvider(state, provider);
38
+ const unsubscribe1 = subscribe(state, testBus, ['a'], jest.fn());
39
+ const unsubscribe2 = subscribe(state, testBus, ['a'], jest.fn());
40
+ expect(provider.onActivate).toBeCalled();
41
+ expect(provider.onDeactivate).not.toBeCalled();
42
+ unsubscribe1();
43
+ expect(provider.onDeactivate).not.toBeCalled();
44
+ unsubscribe2();
45
+ expect(provider.onDeactivate).toBeCalled();
46
+ });
47
+ it('can intercept publishing', () => {
48
+ const state = { root: {} };
49
+ const provider = getTestProvider(['a']);
50
+ const changeFn = jest.fn();
51
+ provider.onPublish = ({ value }) => 'new-' + value;
52
+ addProvider(state, provider);
53
+ subscribe(state, testBus, ['a'], changeFn);
54
+ publish(state, testBus, ['a'], 'test');
55
+ expect(changeFn.mock.calls).toEqual([['new-test', undefined, ['a']]]);
56
+ });
57
+ });
58
+ //# sourceMappingURL=addProvider.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"addProvider.test.js","sourceRoot":"","sources":["../src/addProvider.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGnD,MAAM,OAAO,GAAG,aAAa,EAAE,CAAC;AAEhC,SAAS,eAAe,CAAC,IAAc;IACrC,OAAO;QACL,IAAI;QACJ,UAAU,EAAE,IAAI,CAAC,EAAE,EAAE;QACrB,YAAY,EAAE,IAAI,CAAC,EAAE,EAAE;QACvB,8DAA8D;QAC9D,SAAS,EAAE,IAAI,CAAC,EAAE,EAAS;KAC5B,CAAC;AACJ,CAAC;AAED,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,EAAE,CAAC,oBAAoB,EAAE,GAAG,EAAE;QAC5B,MAAM,KAAK,GAAiB,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;QACzC,MAAM,QAAQ,GAAG,eAAe,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAExC,WAAW,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QAE7B,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,EAAE,SAAS,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAChE,MAAM,KAAK,GAAiB,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;QACzC,MAAM,QAAQ,GAAG,eAAe,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;QAE3B,WAAW,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QAC7B,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,CAAC;QAC3C,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAC/C,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,CAAC;QAC3C,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAC/C,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;QACpE,MAAM,KAAK,GAAiB,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;QACzC,MAAM,QAAQ,GAAG,eAAe,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAExC,WAAW,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QAC7B,MAAM,YAAY,GAAG,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QACjE,MAAM,YAAY,GAAG,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QACjE,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,UAAU,EAAE,CAAC;QACzC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC;QAC/C,YAAY,EAAE,CAAC;QACf,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC;QAC/C,YAAY,EAAE,CAAC;QACf,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,UAAU,EAAE,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;QAClC,MAAM,KAAK,GAAiB,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;QACzC,MAAM,QAAQ,GAAG,eAAe,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;QAE3B,QAAQ,CAAC,SAAS,GAAG,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,MAAM,GAAG,KAAK,CAAC;QAEnD,WAAW,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QAC7B,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,CAAC;QAC3C,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;QAEvC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,EAAE,SAAS,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { DataBus } from './types.js';
2
+ /**
3
+ * Creates a new data bus instance.
4
+ */
5
+ export declare function createDataBus(): DataBus;
@@ -0,0 +1,23 @@
1
+ import { addProvider } from './addProvider.js';
2
+ import { createNode } from './createNode.js';
3
+ import { getData } from './getData.js';
4
+ import { publish } from './publish.js';
5
+ import { subscribe } from './subscribe.js';
6
+ /**
7
+ * Creates a new data bus instance.
8
+ */
9
+ export function createDataBus() {
10
+ const state = {
11
+ root: createNode(),
12
+ };
13
+ const bus = {
14
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
15
+ publish: (path, value) => publish(state, bus, path, value),
16
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
17
+ getData: (path) => getData(state, path),
18
+ subscribe: (path, change) => subscribe(state, bus, path, change),
19
+ addProvider: (provider) => addProvider(state, provider),
20
+ };
21
+ return bus;
22
+ }
23
+ //# sourceMappingURL=createDataBus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createDataBus.js","sourceRoot":"","sources":["../src/createDataBus.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAG3C;;GAEG;AACH,MAAM,UAAU,aAAa;IAC3B,MAAM,KAAK,GAAiB;QAC1B,IAAI,EAAE,UAAU,EAAE;KACnB,CAAC;IAEF,MAAM,GAAG,GAAG;QACV,8DAA8D;QAC9D,OAAO,EAAE,CAAC,IAAc,EAAE,KAAU,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,CAAC;QAEzE,8DAA8D;QAC9D,OAAO,EAAE,CAAc,IAAc,EAAE,EAAE,CAAC,OAAO,CAAQ,KAAK,EAAE,IAAI,CAAC;QAErE,SAAS,EAAE,CAAC,IAAc,EAAE,MAA6B,EAAE,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC;QAEjG,WAAW,EAAE,CAAC,QAAyB,EAAE,EAAE,CAAC,WAAW,CAAC,KAAK,EAAE,QAAQ,CAAC;KACzE,CAAC;IAEF,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,26 @@
1
+ import { createDataBus } from './createDataBus.js';
2
+ import { jest } from '@jest/globals';
3
+ describe('createDataBus', () => {
4
+ it('can pub/sub using a root provider', () => {
5
+ const bus = createDataBus();
6
+ const provider = {
7
+ path: [],
8
+ onActivate: jest.fn(),
9
+ onDeactivate: jest.fn(),
10
+ };
11
+ // Register provider
12
+ bus.addProvider(provider);
13
+ // Set up subscription
14
+ const onNotify = jest.fn();
15
+ const dispose = bus.subscribe(['status'], onNotify);
16
+ // We have not received any published data.
17
+ expect(onNotify).toBeCalledTimes(0);
18
+ // Expect an activation from the root provider.
19
+ expect(provider.onActivate).toBeCalledTimes(1);
20
+ // Dispose the subscription.
21
+ dispose();
22
+ // Expect a deactivation from the root provider.
23
+ expect(provider.onDeactivate).toBeCalledTimes(1);
24
+ });
25
+ });
26
+ //# sourceMappingURL=createDataBus.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createDataBus.test.js","sourceRoot":"","sources":["../src/createDataBus.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG;YACf,IAAI,EAAE,EAAE;YACR,UAAU,EAAE,IAAI,CAAC,EAAE,EAAE;YACrB,YAAY,EAAE,IAAI,CAAC,EAAE,EAAE;SACxB,CAAC;QAEF,oBAAoB;QACpB,GAAG,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;QAE1B,sBAAsB;QACtB,MAAM,QAAQ,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,CAAC;QAEpD,2CAA2C;QAC3C,MAAM,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAEpC,+CAA+C;QAC/C,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAE/C,4BAA4B;QAC5B,OAAO,EAAE,CAAC;QAEV,gDAAgD;QAChD,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { DataBusNode } from './types.js';
2
+ export declare function createNode(name?: string): DataBusNode;
@@ -0,0 +1,6 @@
1
+ export function createNode(name = '') {
2
+ return {
3
+ name,
4
+ };
5
+ }
6
+ //# sourceMappingURL=createNode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createNode.js","sourceRoot":"","sources":["../src/createNode.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,UAAU,CAAC,IAAI,GAAG,EAAE;IAClC,OAAO;QACL,IAAI;KACL,CAAC;AACJ,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { DataBusState } from './types.js';
2
+ /**
3
+ * Gets data containing the corresponding props.
4
+ */
5
+ export declare function getData<TData>(state: DataBusState, path: string[]): TData | undefined;
package/lib/getData.js ADDED
@@ -0,0 +1,9 @@
1
+ import { getNode } from './getNode.js';
2
+ /**
3
+ * Gets data containing the corresponding props.
4
+ */
5
+ export function getData(state, path) {
6
+ const { node } = getNode(state, path);
7
+ return node?.value;
8
+ }
9
+ //# sourceMappingURL=getData.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getData.js","sourceRoot":"","sources":["../src/getData.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC;;GAEG;AACH,MAAM,UAAU,OAAO,CAAQ,KAAmB,EAAE,IAAc;IAChE,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAEtC,OAAO,IAAI,EAAE,KAAK,CAAC;AACrB,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,33 @@
1
+ import { getData } from './getData.js';
2
+ const testState = {
3
+ root: {
4
+ name: '',
5
+ children: {
6
+ a: {
7
+ name: 'a',
8
+ value: 'a',
9
+ providers: [],
10
+ subscribers: new Set(),
11
+ children: {
12
+ b: {
13
+ name: 'b',
14
+ value: 'b',
15
+ providers: [],
16
+ subscribers: new Set(),
17
+ children: {},
18
+ },
19
+ },
20
+ },
21
+ },
22
+ },
23
+ };
24
+ describe('getData', () => {
25
+ it('can get existing data', () => {
26
+ expect(getData(testState, ['a', 'b'])).toEqual('b');
27
+ });
28
+ it('returns undefined on missing data and does not create nodes', () => {
29
+ expect(getData(testState, ['a', 'b', 'c'])).toBeUndefined();
30
+ expect(testState.root.children?.['a']?.children?.['b']?.children?.['c']).toBeUndefined();
31
+ });
32
+ });
33
+ //# sourceMappingURL=getData.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getData.test.js","sourceRoot":"","sources":["../src/getData.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC,MAAM,SAAS,GAAiB;IAC9B,IAAI,EAAE;QACJ,IAAI,EAAE,EAAE;QACR,QAAQ,EAAE;YACR,CAAC,EAAE;gBACD,IAAI,EAAE,GAAG;gBACT,KAAK,EAAE,GAAG;gBACV,SAAS,EAAE,EAAE;gBACb,WAAW,EAAE,IAAI,GAAG,EAAE;gBACtB,QAAQ,EAAE;oBACR,CAAC,EAAE;wBACD,IAAI,EAAE,GAAG;wBACT,KAAK,EAAE,GAAG;wBACV,SAAS,EAAE,EAAE;wBACb,WAAW,EAAE,IAAI,GAAG,EAAE;wBACtB,QAAQ,EAAE,EAAE;qBACb;iBACF;aACF;SACF;KACF;CACF,CAAC;AAEF,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE;IACvB,EAAE,CAAC,uBAAuB,EAAE,GAAG,EAAE;QAC/B,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6DAA6D,EAAE,GAAG,EAAE;QACrE,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;QAC5D,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IAC3F,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { DataBusNode, DataBusState } from './types.js';
2
+ export declare function getNode(state: DataBusState, path: string[]): {
3
+ node: DataBusNode;
4
+ nodePath: DataBusNode[];
5
+ };
6
+ export declare function getNode(state: DataBusState, path: string[], createPath: true): {
7
+ node: DataBusNode;
8
+ nodePath: DataBusNode[];
9
+ };
package/lib/getNode.js ADDED
@@ -0,0 +1,20 @@
1
+ import { createNode } from './createNode.js';
2
+ export function getNode(state, path, createPath) {
3
+ let index = 0;
4
+ let node = state.root;
5
+ const nodePath = [state.root];
6
+ while (node && index < path.length) {
7
+ const pathName = path[index++];
8
+ if (!node.children?.[pathName] && createPath) {
9
+ node.children ?? (node.children = {});
10
+ node.children[pathName] = createNode(pathName);
11
+ }
12
+ node = node.children?.[pathName];
13
+ nodePath.push(node);
14
+ }
15
+ return {
16
+ node,
17
+ nodePath,
18
+ };
19
+ }
20
+ //# sourceMappingURL=getNode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getNode.js","sourceRoot":"","sources":["../src/getNode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAoB7C,MAAM,UAAU,OAAO,CACrB,KAAmB,EACnB,IAAc,EACd,UAAoB;IAKpB,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,IAAI,GAA4B,KAAK,CAAC,IAAI,CAAC;IAC/C,MAAM,QAAQ,GAAkB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAE7C,OAAO,IAAI,IAAI,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE;QAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QAE/B,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,IAAI,UAAU,EAAE;YAC5C,IAAI,CAAC,QAAQ,KAAb,IAAI,CAAC,QAAQ,GAAK,EAAE,EAAC;YACrB,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;SAChD;QAED,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC;QACjC,QAAQ,CAAC,IAAI,CAAC,IAAmB,CAAC,CAAC;KACpC;IAED,OAAO;QACL,IAAI;QACJ,QAAQ;KACT,CAAC;AACJ,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,42 @@
1
+ import { getNode } from './getNode.js';
2
+ function createTestState() {
3
+ return {
4
+ root: {
5
+ name: '',
6
+ children: {
7
+ a: {
8
+ name: 'a',
9
+ children: {
10
+ b: {
11
+ name: 'b',
12
+ },
13
+ },
14
+ },
15
+ },
16
+ },
17
+ };
18
+ }
19
+ describe('getNode', () => {
20
+ it('can return a node', () => {
21
+ const testState = createTestState();
22
+ const { node, nodePath } = getNode(testState, ['a', 'b']);
23
+ expect(node).toBeDefined();
24
+ expect(node.name).toEqual('b');
25
+ expect(nodePath).toEqual([
26
+ testState.root,
27
+ testState.root.children?.['a'],
28
+ testState.root.children?.['a'].children?.['b'],
29
+ ]);
30
+ });
31
+ it('can return undefined on missing path', () => {
32
+ const testState = createTestState();
33
+ expect(getNode(testState, ['a', 'c']).node).toBeUndefined();
34
+ expect(testState.root.children?.['a']?.children?.['c']).toBeUndefined();
35
+ });
36
+ it('can return undefined on missing path but create it when specified', () => {
37
+ const testState = createTestState();
38
+ expect(testState.root.children?.['a']?.children?.['c']).toBeUndefined();
39
+ expect(getNode(testState, ['a', 'c'], true).node).toBeTruthy();
40
+ });
41
+ });
42
+ //# sourceMappingURL=getNode.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getNode.test.js","sourceRoot":"","sources":["../src/getNode.test.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,SAAS,eAAe;IACtB,OAAO;QACL,IAAI,EAAE;YACJ,IAAI,EAAE,EAAE;YACR,QAAQ,EAAE;gBACR,CAAC,EAAE;oBACD,IAAI,EAAE,GAAG;oBACT,QAAQ,EAAE;wBACR,CAAC,EAAE;4BACD,IAAI,EAAE,GAAG;yBACV;qBACF;iBACF;aACF;SACF;KACF,CAAC;AACJ,CAAC;AAED,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE;IACvB,EAAE,CAAC,mBAAmB,EAAE,GAAG,EAAE;QAC3B,MAAM,SAAS,GAAG,eAAe,EAAE,CAAC;QACpC,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;QAE1D,MAAM,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;QAC3B,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC/B,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC;YACvB,SAAS,CAAC,IAAI;YACd,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC;YAC9B,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC;SAC/C,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC9C,MAAM,SAAS,GAAG,eAAe,EAAE,CAAC;QAEpC,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,CAAC;QAC5D,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IAC1E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mEAAmE,EAAE,GAAG,EAAE;QAC3E,MAAM,SAAS,GAAG,eAAe,EAAE,CAAC;QAEpC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;QACxE,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC;IACjE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
package/lib/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export { createDataBus } from './createDataBus.js';
2
+ export type { DataBus, DataBusChangeFunction, DataBusNode, DataBusProvider, DataBusState, DisposeFunction, } from './types.js';
package/lib/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export { createDataBus } from './createDataBus.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { DataBus, DataBusState } from './types.js';
2
+ /**
3
+ * Publishes data to a given dataPath/Id.
4
+ */
5
+ export declare function publish<TData>(state: DataBusState, bus: DataBus, path: string[], value: TData): void;
package/lib/publish.js ADDED
@@ -0,0 +1,23 @@
1
+ import { getNode } from './getNode.js';
2
+ /**
3
+ * Publishes data to a given dataPath/Id.
4
+ */
5
+ export function publish(state, bus, path, value) {
6
+ const { node, nodePath } = getNode(state, path, true);
7
+ const oldValue = node.value;
8
+ // Notify pre-publishing providers and allow them to apply transforms or publish additional metadata.
9
+ for (let i = nodePath.length - 1; i >= 0; i--) {
10
+ nodePath[i].providers?.forEach((provider) => {
11
+ const newValue = provider.onPublish?.({ bus, value, oldValue, path });
12
+ if (newValue !== undefined) {
13
+ value = newValue;
14
+ }
15
+ });
16
+ }
17
+ node.value = value;
18
+ // Notify subscribers
19
+ for (let i = nodePath.length - 1; i >= 0; i--) {
20
+ nodePath[i].subscribers?.forEach((subscriber) => subscriber(value, oldValue, path));
21
+ }
22
+ }
23
+ //# sourceMappingURL=publish.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish.js","sourceRoot":"","sources":["../src/publish.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC;;GAEG;AACH,MAAM,UAAU,OAAO,CAAQ,KAAmB,EAAE,GAAY,EAAE,IAAc,EAAE,KAAY;IAC5F,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC;IAE5B,qGAAqG;IACrG,KAAK,IAAI,CAAC,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE;QAC7C,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;YAC1C,MAAM,QAAQ,GAAG,QAAQ,CAAC,SAAS,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;YAEtE,IAAI,QAAQ,KAAK,SAAS,EAAE;gBAC1B,KAAK,GAAG,QAAQ,CAAC;aAClB;QACH,CAAC,CAAC,CAAC;KACJ;IAED,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IAEnB,qBAAqB;IACrB,KAAK,IAAI,CAAC,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE;QAC7C,QAAQ,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC;KACrF;AACH,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,25 @@
1
+ import { publish } from './publish.js';
2
+ import { createDataBus } from './createDataBus.js';
3
+ const testBus = createDataBus();
4
+ describe('publish', () => {
5
+ it('can publish to an existing value', () => {
6
+ const state = {
7
+ root: {
8
+ children: {
9
+ a: {
10
+ name: 'a',
11
+ value: 42,
12
+ },
13
+ },
14
+ },
15
+ };
16
+ publish(state, testBus, ['a'], 43);
17
+ expect(state.root.children?.['a'].value).toEqual(43);
18
+ });
19
+ it('can publish to a non-existing value', () => {
20
+ const state = { root: {} };
21
+ publish(state, testBus, ['a'], 43);
22
+ expect(state.root.children?.['a'].value).toEqual(43);
23
+ });
24
+ });
25
+ //# sourceMappingURL=publish.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish.test.js","sourceRoot":"","sources":["../src/publish.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGnD,MAAM,OAAO,GAAG,aAAa,EAAE,CAAC;AAEhC,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE;IACvB,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,KAAK,GAAiB;YAC1B,IAAI,EAAE;gBACJ,QAAQ,EAAE;oBACR,CAAC,EAAE;wBACD,IAAI,EAAE,GAAG;wBACT,KAAK,EAAE,EAAE;qBACV;iBACF;aACF;SACF,CAAC;QAEF,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QAEnC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,KAAK,GAAiB,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;QAEzC,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QACnC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { DataBusState, DataBusChangeFunction, DisposeFunction, DataBus } from './types.js';
2
+ export declare function subscribe(state: DataBusState, bus: DataBus, path: string[], change: DataBusChangeFunction): DisposeFunction;
@@ -0,0 +1,44 @@
1
+ import { getNode } from './getNode.js';
2
+ export function subscribe(state, bus, path, change) {
3
+ const { node, nodePath } = getNode(state, path, true);
4
+ const { value } = node;
5
+ const pathString = path.join('/');
6
+ node.subscribers ?? (node.subscribers = new Set());
7
+ node.subscribers.add(change);
8
+ // Fire the initial change with the value.
9
+ if (value !== undefined) {
10
+ change(value, value, path);
11
+ }
12
+ // Activate any deactivated providers available for this path.
13
+ for (let index = nodePath.length - 1; index >= 0; index--) {
14
+ const currentNode = nodePath[index];
15
+ if (currentNode.providers?.length) {
16
+ const activeProviders = (currentNode.activeProviders ?? (currentNode.activeProviders = {}));
17
+ currentNode.providers.forEach((provider) => {
18
+ activeProviders[pathString] ?? (activeProviders[pathString] = { provider, count: 0 });
19
+ if (activeProviders[pathString].count === 0) {
20
+ provider.onActivate?.({ path, bus });
21
+ }
22
+ activeProviders[pathString].count++;
23
+ });
24
+ }
25
+ }
26
+ return () => {
27
+ node.subscribers?.delete(change);
28
+ // Deactivate providers.
29
+ for (let index = nodePath.length - 1; index >= 0; index--) {
30
+ const currentNode = nodePath[index];
31
+ if (currentNode.providers?.length) {
32
+ const activeRecord = currentNode.activeProviders?.[pathString];
33
+ if (activeRecord) {
34
+ activeRecord.count--;
35
+ if (!activeRecord.count) {
36
+ activeRecord?.provider.onDeactivate?.({ path, bus });
37
+ delete currentNode.activeProviders?.[pathString];
38
+ }
39
+ }
40
+ }
41
+ }
42
+ };
43
+ }
44
+ //# sourceMappingURL=subscribe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscribe.js","sourceRoot":"","sources":["../src/subscribe.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC,MAAM,UAAU,SAAS,CACvB,KAAmB,EACnB,GAAY,EACZ,IAAc,EACd,MAA6B;IAE7B,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IACtD,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;IACvB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAElC,IAAI,CAAC,WAAW,KAAhB,IAAI,CAAC,WAAW,GAAK,IAAI,GAAG,EAAyB,EAAC;IACtD,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAE7B,0CAA0C;IAC1C,IAAI,KAAK,KAAK,SAAS,EAAE;QACvB,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;KAC5B;IAED,8DAA8D;IAC9D,KAAK,IAAI,KAAK,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE;QACzD,MAAM,WAAW,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;QAEpC,IAAI,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE;YACjC,MAAM,eAAe,GAAG,CAAC,WAAW,CAAC,eAAe,KAA3B,WAAW,CAAC,eAAe,GAAK,EAAE,EAAC,CAAC;YAE7D,WAAW,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;gBACzC,eAAe,CAAC,UAAU,MAA1B,eAAe,CAAC,UAAU,IAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,EAAC;gBAEvD,IAAI,eAAe,CAAC,UAAU,CAAC,CAAC,KAAK,KAAK,CAAC,EAAE;oBAC3C,QAAQ,CAAC,UAAU,EAAE,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;iBACtC;gBAED,eAAe,CAAC,UAAU,CAAC,CAAC,KAAK,EAAE,CAAC;YACtC,CAAC,CAAC,CAAC;SACJ;KACF;IAED,OAAO,GAAG,EAAE;QACV,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QAEjC,wBAAwB;QACxB,KAAK,IAAI,KAAK,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE;YACzD,MAAM,WAAW,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;YAEpC,IAAI,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE;gBACjC,MAAM,YAAY,GAAG,WAAW,CAAC,eAAe,EAAE,CAAC,UAAU,CAAC,CAAC;gBAE/D,IAAI,YAAY,EAAE;oBAChB,YAAY,CAAC,KAAK,EAAE,CAAC;oBAErB,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE;wBACvB,YAAY,EAAE,QAAQ,CAAC,YAAY,EAAE,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;wBACrD,OAAO,WAAW,CAAC,eAAe,EAAE,CAAC,UAAU,CAAC,CAAC;qBAClD;iBACF;aACF;SACF;IACH,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,66 @@
1
+ import { createDataBus } from './createDataBus.js';
2
+ import { subscribe } from './subscribe.js';
3
+ import { getNode } from './getNode.js';
4
+ import { publish } from './publish.js';
5
+ import { jest } from '@jest/globals';
6
+ const testBus = createDataBus();
7
+ const testFunction = jest.fn();
8
+ describe('subscribe', () => {
9
+ it('can subscribe to missing data', () => {
10
+ const state = { root: {} };
11
+ subscribe(state, testBus, ['a', 'b'], testFunction);
12
+ expect(state.root.children?.['a']?.children?.['b']?.subscribers?.has(testFunction)).toBeTruthy();
13
+ });
14
+ it('can subscribe to existing data', () => {
15
+ const state = { root: {} };
16
+ // initialize nodes.
17
+ getNode(state, ['a', 'b'], true);
18
+ subscribe(state, testBus, ['a', 'b'], testFunction);
19
+ expect(state.root.children?.['a']?.children?.['b'].subscribers?.has(testFunction)).toBeTruthy();
20
+ });
21
+ it('is idempotent', () => {
22
+ const state = { root: {} };
23
+ subscribe(state, testBus, ['a', 'b'], testFunction);
24
+ subscribe(state, testBus, ['a', 'b'], testFunction);
25
+ expect(state.root.children?.['a']?.children?.['b'].subscribers?.size).toEqual(1);
26
+ });
27
+ it('does not fire a change when data is unavailable', () => {
28
+ const state = { root: {} };
29
+ const mockFunction = jest.fn();
30
+ subscribe(state, testBus, ['a', 'b'], mockFunction);
31
+ expect(mockFunction).toBeCalledTimes(0);
32
+ });
33
+ it('fires a change when data is available', () => {
34
+ const state = { root: {} };
35
+ const mockFunction = jest.fn();
36
+ publish(state, testBus, ['a', 'b'], 42);
37
+ subscribe(state, testBus, ['a', 'b'], mockFunction);
38
+ expect(mockFunction).toBeCalledTimes(1);
39
+ });
40
+ it('fires a change when data becomes available', () => {
41
+ const state = { root: {} };
42
+ const mockFunction = jest.fn();
43
+ subscribe(state, testBus, ['a', 'b'], mockFunction);
44
+ expect(mockFunction).toBeCalledTimes(0);
45
+ publish(state, testBus, ['a', 'b'], 42);
46
+ expect(mockFunction).toBeCalledTimes(1);
47
+ });
48
+ it('can subscribe to nested data', () => {
49
+ const state = { root: {} };
50
+ const mockFunction = jest.fn();
51
+ subscribe(state, testBus, ['a'], mockFunction);
52
+ expect(mockFunction).toBeCalledTimes(0);
53
+ publish(state, testBus, ['a', 'b'], 42);
54
+ expect(mockFunction).toBeCalledTimes(1);
55
+ expect(mockFunction.mock.calls[0]).toEqual([42, undefined, ['a', 'b']]);
56
+ });
57
+ it('can unsubscribe', () => {
58
+ const state = { root: {} };
59
+ const mockFunction = jest.fn();
60
+ const unsubscribe = subscribe(state, testBus, ['a', 'b'], mockFunction);
61
+ unsubscribe();
62
+ publish(state, testBus, ['a', 'b'], 42);
63
+ expect(mockFunction).toBeCalledTimes(0);
64
+ });
65
+ });
66
+ //# sourceMappingURL=subscribe.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscribe.test.js","sourceRoot":"","sources":["../src/subscribe.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ // This file is read by tools that parse documentation comments conforming to the TSDoc standard.
2
+ // It should be published with your NPM package. It should not be tracked by Git.
3
+ {
4
+ "tsdocVersion": "0.12",
5
+ "toolPackages": [
6
+ {
7
+ "packageName": "@microsoft/api-extractor",
8
+ "packageVersion": "7.29.0"
9
+ }
10
+ ]
11
+ }
package/lib/types.d.ts ADDED
@@ -0,0 +1,39 @@
1
+ export declare type DataBusChangeFunction = <TData>(value: TData, oldValue: TData, path: string[]) => void;
2
+ export declare type DisposeFunction = () => void;
3
+ export interface DataBusProvider<TData = any> {
4
+ path: string[];
5
+ onActivate?: (options: {
6
+ path: string[];
7
+ bus: DataBus;
8
+ }) => void;
9
+ onDeactivate?: (options: {
10
+ path: string[];
11
+ bus: DataBus;
12
+ }) => void;
13
+ onPublish?: (options: {
14
+ value: TData;
15
+ oldValue: TData;
16
+ path: string[];
17
+ bus: DataBus;
18
+ }) => TData | undefined;
19
+ }
20
+ export interface DataBusNode {
21
+ name?: string;
22
+ value?: any;
23
+ providers?: DataBusProvider[];
24
+ activeProviders?: Record<string, {
25
+ provider: DataBusProvider;
26
+ count: number;
27
+ }>;
28
+ subscribers?: Set<DataBusChangeFunction>;
29
+ children?: Record<string, DataBusNode>;
30
+ }
31
+ export interface DataBusState {
32
+ root: DataBusNode;
33
+ }
34
+ export interface DataBus {
35
+ publish: (path: string[], value: any) => void;
36
+ subscribe: (path: string[], callback: DataBusChangeFunction) => DisposeFunction;
37
+ getData: (path: string[]) => any;
38
+ addProvider: (provider: DataBusProvider) => void;
39
+ }
package/lib/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "@ms-cloudpack/data-bus",
3
- "version": "0.0.2",
4
- "description": "",
3
+ "version": "0.1.0",
4
+ "description": "A data bus implementation.",
5
+ "license": "MIT",
5
6
  "type": "module",
6
7
  "types": "./lib/index.js",
7
8
  "sideEffects": false,
@@ -12,12 +13,15 @@
12
13
  }
13
14
  },
14
15
  "scripts": {
15
- "build": "just-scripts build",
16
- "build:watch": "just-scripts build:watch",
17
- "lint": "just-scripts lint",
18
- "lint:fix": "just-scripts lint:fix",
19
- "test": "just-scripts test",
20
- "test:watch": "just-scripts test:watch"
16
+ "api:update": "cloudpack-scripts api-update",
17
+ "api": "cloudpack-scripts api",
18
+ "build:watch": "cloudpack-scripts build-watch",
19
+ "build": "cloudpack-scripts build",
20
+ "lint:update": "cloudpack-scripts lint-update",
21
+ "lint": "cloudpack-scripts lint",
22
+ "test:update": "cloudpack-scripts test-update",
23
+ "test:watch": "cloudpack-scripts test-watch",
24
+ "test": "cloudpack-scripts test"
21
25
  },
22
26
  "devDependencies": {
23
27
  "@ms-cloudpack/scripts": "*",