@siggn/react 0.1.0 → 0.1.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.
@@ -1,7 +1,6 @@
1
- import { type Msg, Siggn } from '@siggn/core';
2
- import type { SubscriptionOptions } from 'packages/react/src/types';
3
- import { useEffect, useMemo, useRef, type DependencyList } from 'react';
4
-
1
+ import { Msg, Siggn } from '../../core/src/index.ts';
2
+ import { SubscriptionOptions } from 'packages/react/src/types';
3
+ import { DependencyList } from 'react';
5
4
  /**
6
5
  * Creates and returns a `Siggn` instance that persists for the lifetime of the component.
7
6
  * This is useful for creating a message bus scoped to a component and its children.
@@ -11,7 +10,7 @@ import { useEffect, useMemo, useRef, type DependencyList } from 'react';
11
10
  * @category Lifecycle
12
11
  * @since 0.0.1
13
12
  * @example
14
- *
13
+ *
15
14
  ```tsx
16
15
  * function MyComponent() {
17
16
  * const localSiggn = useSiggn<{ type: 'local-event' }>();
@@ -19,11 +18,7 @@ import { useEffect, useMemo, useRef, type DependencyList } from 'react';
19
18
  * }
20
19
  * ```
21
20
  */
22
- export function useSiggn<T extends Msg>(): Siggn<T> {
23
- const siggn = useRef(new Siggn<T>());
24
- return siggn.current;
25
- }
26
-
21
+ export declare function useSiggn<T extends Msg>(): Siggn<T>;
27
22
  /**
28
23
  * Subscribes to messages and automatically unsubscribes when the component unmounts.
29
24
  *
@@ -34,7 +29,7 @@ export function useSiggn<T extends Msg>(): Siggn<T> {
34
29
  * @category Subscription
35
30
  * @since 0.0.1
36
31
  * @example
37
- *
32
+ *
38
33
  ```tsx
39
34
  * import { siggn } from './siggn'; // Your shared instance
40
35
  *
@@ -46,31 +41,9 @@ export function useSiggn<T extends Msg>(): Siggn<T> {
46
41
  * }
47
42
  * ```
48
43
  */
49
- export function useSubscribe<T extends Msg>(
50
- options: SubscriptionOptions<T>,
51
- setup: (
52
- subscribe: <K extends T['type']>(
53
- type: K,
54
- callback: (msg: Extract<T, { type: K }>) => void,
55
- ) => void,
56
- ) => void,
57
- deps: DependencyList = [],
58
- ) {
59
- const instance = useMemo(
60
- () => (options instanceof Siggn ? options : options.instance),
61
- [options],
62
- );
63
- const id = useMemo(() => instance.makeId('id' in options ? options.id : undefined), [instance]);
64
-
65
- useEffect(() => {
66
- instance.subscribeMany(id, setup);
67
-
68
- return () => {
69
- instance.unsubscribe(id);
70
- };
71
- }, [instance, id, ...deps]);
72
- }
73
-
44
+ export declare function useSubscribe<T extends Msg>(options: SubscriptionOptions<T>, setup: (subscribe: <K extends T['type']>(type: K, callback: (msg: Extract<T, {
45
+ type: K;
46
+ }>) => void) => void) => void, deps?: DependencyList): void;
74
47
  /**
75
48
  * Subscribes to all messages on a `Siggn` instance and automatically unsubscribes
76
49
  * when the component unmounts.
@@ -82,7 +55,7 @@ export function useSubscribe<T extends Msg>(
82
55
  * @category Subscription
83
56
  * @since 0.0.1
84
57
  * @example
85
- *
58
+ *
86
59
  ```tsx
87
60
  * import { siggn } from './siggn';
88
61
  *
@@ -94,22 +67,5 @@ export function useSubscribe<T extends Msg>(
94
67
  * }
95
68
  * ```
96
69
  */
97
- export function useSubscribeAll<T extends Msg>(
98
- options: SubscriptionOptions<T>,
99
- callback: (msg: T) => void,
100
- deps: DependencyList = [],
101
- ) {
102
- const instance = useMemo(
103
- () => (options instanceof Siggn ? options : options.instance),
104
- [options],
105
- );
106
- const id = useMemo(() => instance.makeId('id' in options ? options.id : undefined), [instance]);
107
-
108
- useEffect(() => {
109
- instance.subscribeAll(id, callback);
110
-
111
- return () => {
112
- instance.unsubscribeGlobal(id);
113
- };
114
- }, [instance, id, ...deps]);
115
- }
70
+ export declare function useSubscribeAll<T extends Msg>(options: SubscriptionOptions<T>, callback: (msg: T) => void, deps?: DependencyList): void;
71
+ //# sourceMappingURL=hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,GAAG,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,EAA8B,KAAK,cAAc,EAAE,MAAM,OAAO,CAAC;AAExE;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,CAGlD;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,GAAG,EACxC,OAAO,EAAE,mBAAmB,CAAC,CAAC,CAAC,EAC/B,KAAK,EAAE,CACL,SAAS,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,EAC7B,IAAI,EAAE,CAAC,EACP,QAAQ,EAAE,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,EAAE;IAAE,IAAI,EAAE,CAAC,CAAA;CAAE,CAAC,KAAK,IAAI,KAC7C,IAAI,KACN,IAAI,EACT,IAAI,GAAE,cAAmB,QAe1B;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,GAAG,EAC3C,OAAO,EAAE,mBAAmB,CAAC,CAAC,CAAC,EAC/B,QAAQ,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,EAC1B,IAAI,GAAE,cAAmB,QAe1B"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("@siggn/core"),c=require("react");function t(){return c.useRef(new r.Siggn).current}function b(e,s,i=[]){const u=c.useMemo(()=>e instanceof r.Siggn?e:e.instance,[e]),n=c.useMemo(()=>u.makeId("id"in e?e.id:void 0),[u]);c.useEffect(()=>(u.subscribeMany(n,s),()=>{u.unsubscribe(n)}),[u,n,...i])}function a(e,s,i=[]){const u=c.useMemo(()=>e instanceof r.Siggn?e:e.instance,[e]),n=c.useMemo(()=>u.makeId("id"in e?e.id:void 0),[u]);c.useEffect(()=>(u.subscribeAll(n,s),()=>{u.unsubscribeGlobal(n)}),[u,n,...i])}exports.useSiggn=t;exports.useSubscribe=b;exports.useSubscribeAll=a;Object.keys(r).forEach(e=>{e!=="default"&&!Object.prototype.hasOwnProperty.call(exports,e)&&Object.defineProperty(exports,e,{enumerable:!0,get:()=>r[e]})});
2
+ //# sourceMappingURL=index.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs.js","sources":["../src/hooks.ts"],"sourcesContent":["import { type Msg, Siggn } from '@siggn/core';\nimport type { SubscriptionOptions } from 'packages/react/src/types';\nimport { useEffect, useMemo, useRef, type DependencyList } from 'react';\n\n/**\n * Creates and returns a `Siggn` instance that persists for the lifetime of the component.\n * This is useful for creating a message bus scoped to a component and its children.\n *\n * @template T A union of all possible message types for the new instance.\n * @returns A `Siggn<T>` instance.\n * @category Lifecycle\n * @since 0.0.1\n * @example\n * \n```tsx\n * function MyComponent() {\n * const localSiggn = useSiggn<{ type: 'local-event' }>();\n * // ...\n * }\n * ```\n */\nexport function useSiggn<T extends Msg>(): Siggn<T> {\n const siggn = useRef(new Siggn<T>());\n return siggn.current;\n}\n\n/**\n * Subscribes to messages and automatically unsubscribes when the component unmounts.\n *\n * @template T A union of all possible message types.\n * @param options A `Siggn` instance or an object with the instance and an optional subscriber ID.\n * @param setup A function that receives a `subscribe` helper to define subscriptions.\n * @param deps An optional dependency array to control when the subscriptions are re-created.\n * @category Subscription\n * @since 0.0.1\n * @example\n * \n```tsx\n * import { siggn } from './siggn'; // Your shared instance\n *\n * function MyComponent() {\n * useSubscribe(siggn, (subscribe) => {\n * subscribe('user-created', (msg) => console.log(msg.name));\n * });\n * // ...\n * }\n * ```\n */\nexport function useSubscribe<T extends Msg>(\n options: SubscriptionOptions<T>,\n setup: (\n subscribe: <K extends T['type']>(\n type: K,\n callback: (msg: Extract<T, { type: K }>) => void,\n ) => void,\n ) => void,\n deps: DependencyList = [],\n) {\n const instance = useMemo(\n () => (options instanceof Siggn ? options : options.instance),\n [options],\n );\n const id = useMemo(() => instance.makeId('id' in options ? options.id : undefined), [instance]);\n\n useEffect(() => {\n instance.subscribeMany(id, setup);\n\n return () => {\n instance.unsubscribe(id);\n };\n }, [instance, id, ...deps]);\n}\n\n/**\n * Subscribes to all messages on a `Siggn` instance and automatically unsubscribes\n * when the component unmounts.\n *\n * @template T A union of all possible message types.\n * @param options A `Siggn` instance or an object with the instance and an optional subscriber ID.\n * @param callback The function to call for any message.\n * @param deps An optional dependency array to control when the subscription is re-created.\n * @category Subscription\n * @since 0.0.1\n * @example\n * \n```tsx\n * import { siggn } from './siggn';\n *\n * function LoggerComponent() {\n * useSubscribeAll(siggn, (msg) => {\n * console.log(`[LOG]: ${msg.type}`);\n * }, []);\n * // ...\n * }\n * ```\n */\nexport function useSubscribeAll<T extends Msg>(\n options: SubscriptionOptions<T>,\n callback: (msg: T) => void,\n deps: DependencyList = [],\n) {\n const instance = useMemo(\n () => (options instanceof Siggn ? options : options.instance),\n [options],\n );\n const id = useMemo(() => instance.makeId('id' in options ? options.id : undefined), [instance]);\n\n useEffect(() => {\n instance.subscribeAll(id, callback);\n\n return () => {\n instance.unsubscribeGlobal(id);\n };\n }, [instance, id, ...deps]);\n}\n"],"names":["useSiggn","useRef","Siggn","useSubscribe","options","setup","deps","instance","useMemo","id","useEffect","useSubscribeAll","callback"],"mappings":"kIAqBO,SAASA,GAAoC,CAElD,OADcC,EAAAA,OAAO,IAAIC,EAAAA,KAAU,EACtB,OACf,CAwBO,SAASC,EACdC,EACAC,EAMAC,EAAuB,CAAA,EACvB,CACA,MAAMC,EAAWC,EAAAA,QACf,IAAOJ,aAAmBF,EAAAA,MAAQE,EAAUA,EAAQ,SACpD,CAACA,CAAO,CAAA,EAEJK,EAAKD,EAAAA,QAAQ,IAAMD,EAAS,OAAO,OAAQH,EAAUA,EAAQ,GAAK,MAAS,EAAG,CAACG,CAAQ,CAAC,EAE9FG,EAAAA,UAAU,KACRH,EAAS,cAAcE,EAAIJ,CAAK,EAEzB,IAAM,CACXE,EAAS,YAAYE,CAAE,CACzB,GACC,CAACF,EAAUE,EAAI,GAAGH,CAAI,CAAC,CAC5B,CAyBO,SAASK,EACdP,EACAQ,EACAN,EAAuB,CAAA,EACvB,CACA,MAAMC,EAAWC,EAAAA,QACf,IAAOJ,aAAmBF,EAAAA,MAAQE,EAAUA,EAAQ,SACpD,CAACA,CAAO,CAAA,EAEJK,EAAKD,EAAAA,QAAQ,IAAMD,EAAS,OAAO,OAAQH,EAAUA,EAAQ,GAAK,MAAS,EAAG,CAACG,CAAQ,CAAC,EAE9FG,EAAAA,UAAU,KACRH,EAAS,aAAaE,EAAIG,CAAQ,EAE3B,IAAM,CACXL,EAAS,kBAAkBE,CAAE,CAC/B,GACC,CAACF,EAAUE,EAAI,GAAGH,CAAI,CAAC,CAC5B"}
@@ -0,0 +1,3 @@
1
+ export * from './hooks.js';
2
+ export * from '../../core/src/index.ts';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC"}
@@ -0,0 +1,30 @@
1
+ import { Siggn as s } from "@siggn/core";
2
+ export * from "@siggn/core";
3
+ import { useRef as t, useMemo as i, useEffect as b } from "react";
4
+ function d() {
5
+ return t(new s()).current;
6
+ }
7
+ function g(e, r, u = []) {
8
+ const n = i(
9
+ () => e instanceof s ? e : e.instance,
10
+ [e]
11
+ ), c = i(() => n.makeId("id" in e ? e.id : void 0), [n]);
12
+ b(() => (n.subscribeMany(c, r), () => {
13
+ n.unsubscribe(c);
14
+ }), [n, c, ...u]);
15
+ }
16
+ function m(e, r, u = []) {
17
+ const n = i(
18
+ () => e instanceof s ? e : e.instance,
19
+ [e]
20
+ ), c = i(() => n.makeId("id" in e ? e.id : void 0), [n]);
21
+ b(() => (n.subscribeAll(c, r), () => {
22
+ n.unsubscribeGlobal(c);
23
+ }), [n, c, ...u]);
24
+ }
25
+ export {
26
+ d as useSiggn,
27
+ g as useSubscribe,
28
+ m as useSubscribeAll
29
+ };
30
+ //# sourceMappingURL=index.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.es.js","sources":["../src/hooks.ts"],"sourcesContent":["import { type Msg, Siggn } from '@siggn/core';\nimport type { SubscriptionOptions } from 'packages/react/src/types';\nimport { useEffect, useMemo, useRef, type DependencyList } from 'react';\n\n/**\n * Creates and returns a `Siggn` instance that persists for the lifetime of the component.\n * This is useful for creating a message bus scoped to a component and its children.\n *\n * @template T A union of all possible message types for the new instance.\n * @returns A `Siggn<T>` instance.\n * @category Lifecycle\n * @since 0.0.1\n * @example\n * \n```tsx\n * function MyComponent() {\n * const localSiggn = useSiggn<{ type: 'local-event' }>();\n * // ...\n * }\n * ```\n */\nexport function useSiggn<T extends Msg>(): Siggn<T> {\n const siggn = useRef(new Siggn<T>());\n return siggn.current;\n}\n\n/**\n * Subscribes to messages and automatically unsubscribes when the component unmounts.\n *\n * @template T A union of all possible message types.\n * @param options A `Siggn` instance or an object with the instance and an optional subscriber ID.\n * @param setup A function that receives a `subscribe` helper to define subscriptions.\n * @param deps An optional dependency array to control when the subscriptions are re-created.\n * @category Subscription\n * @since 0.0.1\n * @example\n * \n```tsx\n * import { siggn } from './siggn'; // Your shared instance\n *\n * function MyComponent() {\n * useSubscribe(siggn, (subscribe) => {\n * subscribe('user-created', (msg) => console.log(msg.name));\n * });\n * // ...\n * }\n * ```\n */\nexport function useSubscribe<T extends Msg>(\n options: SubscriptionOptions<T>,\n setup: (\n subscribe: <K extends T['type']>(\n type: K,\n callback: (msg: Extract<T, { type: K }>) => void,\n ) => void,\n ) => void,\n deps: DependencyList = [],\n) {\n const instance = useMemo(\n () => (options instanceof Siggn ? options : options.instance),\n [options],\n );\n const id = useMemo(() => instance.makeId('id' in options ? options.id : undefined), [instance]);\n\n useEffect(() => {\n instance.subscribeMany(id, setup);\n\n return () => {\n instance.unsubscribe(id);\n };\n }, [instance, id, ...deps]);\n}\n\n/**\n * Subscribes to all messages on a `Siggn` instance and automatically unsubscribes\n * when the component unmounts.\n *\n * @template T A union of all possible message types.\n * @param options A `Siggn` instance or an object with the instance and an optional subscriber ID.\n * @param callback The function to call for any message.\n * @param deps An optional dependency array to control when the subscription is re-created.\n * @category Subscription\n * @since 0.0.1\n * @example\n * \n```tsx\n * import { siggn } from './siggn';\n *\n * function LoggerComponent() {\n * useSubscribeAll(siggn, (msg) => {\n * console.log(`[LOG]: ${msg.type}`);\n * }, []);\n * // ...\n * }\n * ```\n */\nexport function useSubscribeAll<T extends Msg>(\n options: SubscriptionOptions<T>,\n callback: (msg: T) => void,\n deps: DependencyList = [],\n) {\n const instance = useMemo(\n () => (options instanceof Siggn ? options : options.instance),\n [options],\n );\n const id = useMemo(() => instance.makeId('id' in options ? options.id : undefined), [instance]);\n\n useEffect(() => {\n instance.subscribeAll(id, callback);\n\n return () => {\n instance.unsubscribeGlobal(id);\n };\n }, [instance, id, ...deps]);\n}\n"],"names":["useSiggn","useRef","Siggn","useSubscribe","options","setup","deps","instance","useMemo","id","useEffect","useSubscribeAll","callback"],"mappings":";;;AAqBO,SAASA,IAAoC;AAElD,SADcC,EAAO,IAAIC,GAAU,EACtB;AACf;AAwBO,SAASC,EACdC,GACAC,GAMAC,IAAuB,CAAA,GACvB;AACA,QAAMC,IAAWC;AAAA,IACf,MAAOJ,aAAmBF,IAAQE,IAAUA,EAAQ;AAAA,IACpD,CAACA,CAAO;AAAA,EAAA,GAEJK,IAAKD,EAAQ,MAAMD,EAAS,OAAO,QAAQH,IAAUA,EAAQ,KAAK,MAAS,GAAG,CAACG,CAAQ,CAAC;AAE9F,EAAAG,EAAU,OACRH,EAAS,cAAcE,GAAIJ,CAAK,GAEzB,MAAM;AACX,IAAAE,EAAS,YAAYE,CAAE;AAAA,EACzB,IACC,CAACF,GAAUE,GAAI,GAAGH,CAAI,CAAC;AAC5B;AAyBO,SAASK,EACdP,GACAQ,GACAN,IAAuB,CAAA,GACvB;AACA,QAAMC,IAAWC;AAAA,IACf,MAAOJ,aAAmBF,IAAQE,IAAUA,EAAQ;AAAA,IACpD,CAACA,CAAO;AAAA,EAAA,GAEJK,IAAKD,EAAQ,MAAMD,EAAS,OAAO,QAAQH,IAAUA,EAAQ,KAAK,MAAS,GAAG,CAACG,CAAQ,CAAC;AAE9F,EAAAG,EAAU,OACRH,EAAS,aAAaE,GAAIG,CAAQ,GAE3B,MAAM;AACX,IAAAL,EAAS,kBAAkBE,CAAE;AAAA,EAC/B,IACC,CAACF,GAAUE,GAAI,GAAGH,CAAI,CAAC;AAC5B;"}
@@ -0,0 +1,6 @@
1
+ import { Msg, Siggn } from '../../core/src/index.ts';
2
+ export type SubscriptionOptions<T extends Msg> = Siggn<T> | {
3
+ instance: Siggn<T>;
4
+ id?: string;
5
+ };
6
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAE9C,MAAM,MAAM,mBAAmB,CAAC,CAAC,SAAS,GAAG,IACzC,KAAK,CAAC,CAAC,CAAC,GACR;IACE,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IACnB,EAAE,CAAC,EAAE,MAAM,CAAC;CACb,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@siggn/react",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "A lightweight type safe message bus system for React",
5
5
  "keywords": [
6
6
  "pub/sub",
@@ -36,6 +36,9 @@
36
36
  }
37
37
  },
38
38
  "type": "module",
39
+ "files": [
40
+ "dist"
41
+ ],
39
42
  "sideEffects": false,
40
43
  "devDependencies": {
41
44
  "typescript": "^5.9.3",
package/.prettierrc DELETED
@@ -1,16 +0,0 @@
1
- {
2
- "arrowParens": "always",
3
- "bracketSpacing": true,
4
- "htmlWhitespaceSensitivity": "css",
5
- "insertPragma": false,
6
- "jsxSingleQuote": true,
7
- "printWidth": 100,
8
- "proseWrap": "always",
9
- "quoteProps": "as-needed",
10
- "requirePragma": false,
11
- "semi": true,
12
- "singleQuote": true,
13
- "tabWidth": 2,
14
- "trailingComma": "all",
15
- "useTabs": false
16
- }
package/CHANGELOG.md DELETED
@@ -1,28 +0,0 @@
1
- # @siggn/react
2
-
3
- ## 0.1.0
4
-
5
- ### Minor Changes
6
-
7
- - [`54e3afd`](https://github.com/Guiguerreiro39/siggn/commit/54e3afd430bdb73ef0549ebdfbf9fc6f76bc62b1)
8
- Thanks [@Guiguerreiro39](https://github.com/Guiguerreiro39)! - - Introduced automatic garbage
9
- collection to prevent memory leaks.
10
- - Added code documentation
11
- - Added `subscriptionsCount` property to `Siggn`
12
-
13
- ### Patch Changes
14
-
15
- - Updated dependencies
16
- [[`54e3afd`](https://github.com/Guiguerreiro39/siggn/commit/54e3afd430bdb73ef0549ebdfbf9fc6f76bc62b1)]:
17
- - @siggn/core@0.1.0
18
-
19
- ## 0.0.1
20
-
21
- ### Patch Changes
22
-
23
- - [`d2a88af`](https://github.com/Guiguerreiro39/siggn/commit/d2a88af8e484f28e436c594cd3238379295941a2)
24
- Thanks [@Guiguerreiro39](https://github.com/Guiguerreiro39)! - Added react hooks support
25
-
26
- - Updated dependencies
27
- [[`d2a88af`](https://github.com/Guiguerreiro39/siggn/commit/d2a88af8e484f28e436c594cd3238379295941a2)]:
28
- - @siggn/core@0.0.5
package/src/index.ts DELETED
@@ -1,2 +0,0 @@
1
- export * from './hooks.js';
2
- export * from '@siggn/core';
package/src/types.ts DELETED
@@ -1,8 +0,0 @@
1
- import type { Msg, Siggn } from '@siggn/core';
2
-
3
- export type SubscriptionOptions<T extends Msg> =
4
- | Siggn<T>
5
- | {
6
- instance: Siggn<T>;
7
- id?: string;
8
- };
@@ -1,270 +0,0 @@
1
- import { test, expect, describe, beforeEach, afterEach, vi } from 'vitest';
2
- import { useSiggn, useSubscribe, useSubscribeAll } from '../src/hooks.js';
3
- import { Siggn } from '@siggn/core';
4
- import { act, render, renderHook, screen, cleanup } from '@testing-library/react';
5
- import { useState } from 'react';
6
-
7
- type Msg =
8
- | {
9
- type: 'increment_count';
10
- value: number;
11
- }
12
- | { type: 'decrement_count'; value: number }
13
- | { type: 'custom_event'; data: string }
14
- | { type: 'dependency_changed'; newValue: number };
15
-
16
- describe('@siggn/react', () => {
17
- let siggn: Siggn<Msg>;
18
-
19
- beforeEach(() => {
20
- const { result } = renderHook(() => useSiggn<Msg>());
21
- siggn = result.current;
22
- });
23
-
24
- afterEach(() => {
25
- cleanup();
26
- });
27
-
28
- test('user should be able to create a siggn instance and subscribe using hooks', () => {
29
- function TestComponent() {
30
- const [count, setCount] = useState(0);
31
-
32
- useSubscribe(siggn, (subscribe) => {
33
- subscribe('increment_count', (msg) => {
34
- setCount((prev) => prev + msg.value);
35
- });
36
-
37
- subscribe('decrement_count', (msg) => {
38
- setCount((prev) => prev - msg.value);
39
- });
40
- });
41
-
42
- return <div data-testid='value'>{count}</div>;
43
- }
44
-
45
- render(<TestComponent />);
46
-
47
- expect(screen.getByTestId('value')).toHaveTextContent('0');
48
-
49
- act(() => {
50
- siggn.publish({ type: 'increment_count', value: 4 });
51
- });
52
-
53
- expect(screen.getByTestId('value')).toHaveTextContent('4');
54
-
55
- act(() => {
56
- siggn.publish({ type: 'decrement_count', value: 2 });
57
- });
58
-
59
- expect(screen.getByTestId('value')).toHaveTextContent('2');
60
- });
61
-
62
- test('useSiggn should return a stable instance across re-renders', () => {
63
- const { result, rerender } = renderHook(() => useSiggn<Msg>());
64
- const firstInstance = result.current;
65
-
66
- rerender(); // Re-render the hook
67
-
68
- const secondInstance = result.current;
69
- expect(firstInstance).toBe(secondInstance); // Should be the same instance
70
- });
71
-
72
- test('useSubscribe should work with explicit id in options', () => {
73
- let receivedData: string | null = null;
74
- const customId = 'my-custom-subscriber';
75
-
76
- function TestComponent() {
77
- useSubscribe({ instance: siggn, id: customId }, (subscribe) => {
78
- subscribe('custom_event', (msg) => {
79
- receivedData = msg.data;
80
- });
81
- });
82
- return null;
83
- }
84
-
85
- render(<TestComponent />);
86
-
87
- act(() => {
88
- siggn.publish({ type: 'custom_event', data: 'hello' });
89
- });
90
-
91
- expect(receivedData).toBe('hello');
92
-
93
- // Manually unsubscribe using the custom ID
94
- act(() => {
95
- siggn.unsubscribe(customId);
96
- });
97
-
98
- act(() => {
99
- siggn.publish({ type: 'custom_event', data: 'world' });
100
- });
101
-
102
- // Should not receive 'world' as it's unsubscribed
103
- expect(receivedData).toBe('hello');
104
- });
105
-
106
- test('useSubscribe should re-subscribe when dependencies change', () => {
107
- let callCount = 0;
108
- let lastReceivedValue = 0;
109
-
110
- function TestComponent({ depValue }: { depValue: number }) {
111
- useSubscribe(
112
- siggn,
113
- (subscribe) => {
114
- callCount++; // This should increment when subscription is re-established
115
- subscribe('dependency_changed', (msg) => {
116
- lastReceivedValue = msg.newValue + depValue; // Use depValue in callback
117
- });
118
- },
119
- [depValue], // Dependency array includes depValue
120
- );
121
- return <div data-testid='last-value'>{lastReceivedValue}</div>;
122
- }
123
-
124
- const { rerender } = render(<TestComponent depValue={10} />);
125
-
126
- act(() => {
127
- siggn.publish({ type: 'dependency_changed', newValue: 5 });
128
- });
129
- expect(lastReceivedValue).toBe(15); // 5 + 10
130
- expect(callCount).toBe(1);
131
-
132
- rerender(<TestComponent depValue={20} />); // Change dependency
133
-
134
- act(() => {
135
- siggn.publish({ type: 'dependency_changed', newValue: 5 });
136
- });
137
-
138
- expect(lastReceivedValue).toBe(25); // 5 + 20
139
- expect(callCount).toBe(2); // Subscription should have been re-established
140
- });
141
-
142
- test('useSubscribe should automatically unsubscribe on component unmount', () => {
143
- let receivedMessage: string | null = null;
144
-
145
- function TestComponent() {
146
- useSubscribe(siggn, (subscribe) => {
147
- subscribe('custom_event', (msg) => {
148
- receivedMessage = msg.data;
149
- });
150
- });
151
- return null;
152
- }
153
-
154
- const { unmount } = render(<TestComponent />);
155
-
156
- act(() => {
157
- siggn.publish({ type: 'custom_event', data: 'first message' });
158
- });
159
- expect(receivedMessage).toBe('first message');
160
-
161
- receivedMessage = null; // Reset for next check
162
-
163
- unmount(); // Unmount the component
164
-
165
- act(() => {
166
- siggn.publish({ type: 'custom_event', data: 'second message' });
167
- });
168
-
169
- // After unmount, the subscription should be gone
170
- expect(receivedMessage).toBeNull();
171
- });
172
-
173
- test('useSubscribeAll should receive all messages', () => {
174
- const receivedMessages: Msg[] = [];
175
- const callback = vi.fn((msg: Msg) => {
176
- receivedMessages.push(msg);
177
- });
178
-
179
- function TestComponent() {
180
- useSubscribeAll(siggn, callback);
181
- return null;
182
- }
183
-
184
- render(<TestComponent />);
185
-
186
- act(() => {
187
- siggn.publish({ type: 'increment_count', value: 1 });
188
- siggn.publish({ type: 'custom_event', data: 'test' });
189
- });
190
-
191
- expect(callback).toHaveBeenCalledTimes(2);
192
- expect(receivedMessages).toEqual([
193
- { type: 'increment_count', value: 1 },
194
- { type: 'custom_event', data: 'test' },
195
- ]);
196
- });
197
-
198
- test('useSubscribeAll should automatically unsubscribe on component unmount', () => {
199
- const callback = vi.fn();
200
-
201
- function TestComponent() {
202
- useSubscribeAll(siggn, callback);
203
- return null;
204
- }
205
-
206
- const { unmount } = render(<TestComponent />);
207
-
208
- act(() => {
209
- siggn.publish({ type: 'increment_count', value: 1 });
210
- });
211
- expect(callback).toHaveBeenCalledTimes(1);
212
-
213
- unmount();
214
-
215
- act(() => {
216
- siggn.publish({ type: 'custom_event', data: 'after unmount' });
217
- });
218
-
219
- expect(callback).toHaveBeenCalledTimes(1); // Should not be called again
220
- });
221
-
222
- test('useSubscribeAll should re-subscribe when dependencies change', () => {
223
- const callback = vi.fn();
224
-
225
- function TestComponent({ dep }: { dep: number }) {
226
- useSubscribeAll(siggn, callback, [dep]);
227
- return null;
228
- }
229
-
230
- const { rerender } = render(<TestComponent dep={1} />);
231
-
232
- act(() => {
233
- siggn.publish({ type: 'increment_count', value: 1 });
234
- });
235
- expect(callback).toHaveBeenCalledTimes(1);
236
-
237
- rerender(<TestComponent dep={2} />);
238
-
239
- act(() => {
240
- siggn.publish({ type: 'increment_count', value: 2 });
241
- });
242
- expect(callback).toHaveBeenCalledTimes(2);
243
- });
244
-
245
- test('useSubscribeAll should work with explicit id in options', () => {
246
- const callback = vi.fn();
247
- const customId = 'my-global-subscriber';
248
-
249
- function TestComponent() {
250
- useSubscribeAll({ instance: siggn, id: customId }, callback);
251
- return null;
252
- }
253
-
254
- render(<TestComponent />);
255
-
256
- act(() => {
257
- siggn.publish({ type: 'increment_count', value: 1 });
258
- });
259
- expect(callback).toHaveBeenCalledTimes(1);
260
-
261
- act(() => {
262
- siggn.unsubscribeGlobal(customId);
263
- });
264
-
265
- act(() => {
266
- siggn.publish({ type: 'increment_count', value: 2 });
267
- });
268
- expect(callback).toHaveBeenCalledTimes(1); // Should not be called again
269
- });
270
- });
@@ -1,10 +0,0 @@
1
- {
2
- "extends": "./tsconfig.src.json",
3
- "compilerOptions": {
4
- "tsBuildInfoFile": ".tsbuildinfo/build.tsbuildinfo",
5
- "outDir": "dist",
6
- "declarationDir": "dist",
7
- "stripInternal": true
8
- },
9
- "references": [{ "path": "../core" }]
10
- }
@@ -1,14 +0,0 @@
1
- {
2
- "extends": "../../tsconfig.base.json",
3
- "include": ["examples"],
4
- "references": [
5
- {
6
- "path": "tsconfig.build.json"
7
- }
8
- ],
9
- "compilerOptions": {
10
- "tsBuildInfoFile": ".tsbuildinfo/examples.tsbuildinfo",
11
- "rootDir": "examples",
12
- "noEmit": true
13
- }
14
- }
package/tsconfig.json DELETED
@@ -1,14 +0,0 @@
1
- {
2
- "extends": "../../tsconfig.base.json",
3
- "references": [
4
- {
5
- "path": "tsconfig.src.json"
6
- },
7
- {
8
- "path": "tsconfig.test.json"
9
- },
10
- {
11
- "path": "tsconfig.examples.json"
12
- }
13
- ]
14
- }
package/tsconfig.src.json DELETED
@@ -1,10 +0,0 @@
1
- {
2
- "extends": "../../tsconfig.base.json",
3
- "include": ["src"],
4
- "compilerOptions": {
5
- "tsBuildInfoFile": ".tsbuildinfo/src.tsbuildinfo",
6
- "rootDir": "src",
7
- "outDir": "dist"
8
- },
9
- "references": [{ "path": "../core" }]
10
- }
@@ -1,16 +0,0 @@
1
- {
2
- "extends": "../../tsconfig.base.json",
3
- "include": ["tests"],
4
- "references": [
5
- {
6
- "path": "tsconfig.src.json"
7
- }
8
- ],
9
- "compilerOptions": {
10
- "tsBuildInfoFile": ".tsbuildinfo/test.tsbuildinfo",
11
- "rootDir": "tests",
12
- "noEmit": true,
13
- "jsx": "react-jsx",
14
- "types": ["@testing-library/jest-dom", "vitest/globals"]
15
- }
16
- }
package/vite.config.ts DELETED
@@ -1,49 +0,0 @@
1
- import { defineConfig } from 'vite';
2
- import react from '@vitejs/plugin-react';
3
- import dts from 'vite-plugin-dts';
4
- import path from 'path';
5
-
6
- export default defineConfig({
7
- resolve: {
8
- alias: {
9
- '@siggn/core': path.resolve(__dirname, '../core/src/index.ts'),
10
- },
11
- },
12
- build: {
13
- lib: {
14
- entry: 'src/index.ts',
15
- name: 'SiggnReact',
16
- formats: ['es', 'cjs'],
17
- fileName: (format) => `index.${format}.js`,
18
- },
19
- sourcemap: true,
20
- outDir: 'dist',
21
- emptyOutDir: true,
22
- rollupOptions: {
23
- // Prevent bundling peer dependencies like React, etc.
24
- external: ['react', 'react-dom', '@siggn/core'],
25
- output: {
26
- globals: {
27
- react: 'React',
28
- 'react-dom': 'ReactDOM',
29
- '@siggn/core': 'SiggnCore',
30
- },
31
- },
32
- },
33
- },
34
- test: {
35
- environment: 'jsdom',
36
- globals: true,
37
- setupFiles: './vitest.setup.ts',
38
- },
39
- plugins: [
40
- react(),
41
- dts({
42
- insertTypesEntry: true,
43
- tsconfigPath: 'tsconfig.build.json',
44
- outDir: 'dist',
45
- include: ['src'],
46
- exclude: ['src/**/*.test.ts', 'tests/**'],
47
- }),
48
- ],
49
- });
package/vitest.setup.ts DELETED
@@ -1,7 +0,0 @@
1
- import '@testing-library/jest-dom/vitest';
2
- import { cleanup } from '@testing-library/react';
3
- import { afterEach } from 'vitest';
4
-
5
- afterEach(() => {
6
- cleanup();
7
- });