@siggn/react 0.1.3 → 0.1.4

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.
package/README.md CHANGED
@@ -49,7 +49,7 @@ Alternatively, you can use the `useSiggn` hook to create a `Siggn` instance that
49
49
 
50
50
  ### 2. Subscribe to Events in a Component
51
51
 
52
- Use the `useSubscribe` hook to listen for messages. It automatically handles subscribing and unsubscribing.
52
+ Use the `useSubscribe` hook to listen for a message. It automatically handles subscribing and unsubscribing.
53
53
 
54
54
  ```tsx
55
55
  // src/components/Notification.tsx
@@ -60,7 +60,30 @@ import { siggn, type Message } from '../siggn';
60
60
  function Notification() {
61
61
  const [notification, setNotification] = useState<string | null>(null);
62
62
 
63
- useSubscribe(siggn, (subscribe) => {
63
+ useSubscribe(siggn, 'user_login', (msg) => {
64
+ setNotification(`Welcome, ${msg.name}!`);
65
+ });
66
+
67
+ if (!notification) {
68
+ return null;
69
+ }
70
+
71
+ return <div className='notification'>{notification}</div>;
72
+ }
73
+ ```
74
+
75
+ You can also use the `useSubscribeMany` hook to listen for multiple messages. It automatically handles subscribing and unsubscribing.
76
+
77
+ ```tsx
78
+ // src/components/Notification.tsx
79
+ import { useState } from 'react';
80
+ import { useSubscribeMany } from '@siggn/react';
81
+ import { siggn, type Message } from '../siggn';
82
+
83
+ function Notification() {
84
+ const [notification, setNotification] = useState<string | null>(null);
85
+
86
+ useSubscribeMany(siggn, (subscribe) => {
64
87
  subscribe('user_login', (msg) => {
65
88
  setNotification(`Welcome, ${msg.name}!`);
66
89
  });
package/dist/hooks.d.ts CHANGED
@@ -20,7 +20,7 @@ import { DependencyList } from 'react';
20
20
  */
21
21
  export declare function useSiggn<T extends Msg>(): Siggn<T>;
22
22
  /**
23
- * Subscribes to messages and automatically unsubscribes when the component unmounts.
23
+ * Subscribes to multiple messages and automatically unsubscribes when the component unmounts.
24
24
  *
25
25
  * @template T A union of all possible message types.
26
26
  * @param options A `Siggn` instance or an object with the instance and an optional subscriber ID.
@@ -34,16 +34,40 @@ export declare function useSiggn<T extends Msg>(): Siggn<T>;
34
34
  * import { siggn } from './siggn'; // Your shared instance
35
35
  *
36
36
  * function MyComponent() {
37
- * useSubscribe(siggn, (subscribe) => {
37
+ * useSubscribeMany(siggn, (subscribe) => {
38
38
  * subscribe('user-created', (msg) => console.log(msg.name));
39
+ * subscribe('user-updated', (msg) => console.log(msg.name));
39
40
  * });
40
41
  * // ...
41
42
  * }
42
43
  * ```
43
44
  */
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;
45
+ export declare function useSubscribeMany<M extends Msg>(options: SubscriptionOptions<M>, setup: (subscribe: <T extends M['type']>(type: T, callback: (msg: Extract<M, {
46
+ type: T;
46
47
  }>) => void) => void) => void, deps?: DependencyList): void;
48
+ /**
49
+ * Subscribes to a single message and automatically unsubscribe when the component unmounts.
50
+ *
51
+ * @template T A union of all possible message types.
52
+ * @param options A `Siggn` instance or an object with the instance and an optional subscriber ID.
53
+ * @param setup A function that receives a `subscribe` helper to define subscriptions.
54
+ * @param deps An optional dependency array to control when the subscriptions are re-created.
55
+ * @category Subscription
56
+ * @since 0.0.1
57
+ * @example
58
+ *
59
+ ```tsx
60
+ * import { siggn } from './siggn'; // Your shared instance
61
+ *
62
+ * function MyComponent() {
63
+ * useSubscribe(siggn, 'user-created', (msg) => console.log(msg.name));
64
+ * // ...
65
+ * }
66
+ * ```
67
+ */
68
+ export declare function useSubscribe<M extends Msg, T extends M['type']>(options: SubscriptionOptions<M>, type: T, callback: (msg: Extract<M, {
69
+ type: T;
70
+ }>) => void, deps?: DependencyList): void;
47
71
  /**
48
72
  * Subscribes to all messages on a `Siggn` instance and automatically unsubscribes
49
73
  * when the component unmounts.
@@ -1 +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"}
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,EAAgC,KAAK,cAAc,EAAE,MAAM,OAAO,CAAC;AAE1E;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,CAGlD;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,GAAG,EAC5C,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;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,EAC7D,OAAO,EAAE,mBAAmB,CAAC,CAAC,CAAC,EAC/B,IAAI,EAAE,CAAC,EACP,QAAQ,EAAE,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,EAAE;IAAE,IAAI,EAAE,CAAC,CAAA;CAAE,CAAC,KAAK,IAAI,EAChD,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"}
package/dist/index.cjs.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=require("react");class b{nextId=0;subscriptions;globalSubscriptions=[];registry=new FinalizationRegistry(s=>{this.unsubscribe(s)});registryGlobal=new FinalizationRegistry(s=>{this.unsubscribeGlobal(s)});constructor(){this.subscriptions=new Map}createClone(){return new b}makeId(s){return s??`sub_${(this.nextId++).toString(36)}`}make(s){return{subscribe:(i,e)=>{this.subscribe(s,i,e)},unsubscribe:()=>{this.unsubscribe(s)},subscribeMany:i=>{this.subscribeMany(s,i)},subscribeAll:i=>{this.subscribeAll(s,i)}}}subscribeMany(s,i){i((e,r)=>this.subscribe(s,e,r))}subscribe(s,i,e){this.subscriptions.has(i)||this.subscriptions.set(i,[]),this.registry.register(e,s),this.subscriptions.get(i)?.push({id:s,ref:new WeakRef(e)})}subscribeAll(s,i){this.registryGlobal.register(i,s),this.globalSubscriptions.push({id:s,ref:new WeakRef(i)})}publish(s){this.globalSubscriptions.forEach(i=>{const e=i.ref.deref();if(!e){this.unsubscribeGlobal(i.id);return}e(s)}),this.subscriptions.has(s.type)&&this.subscriptions.get(s.type)?.forEach(i=>{const e=i.ref.deref();if(!e){this.unsubscribe(i.id);return}e(s)})}unsubscribe(s){this.unsubscribeGlobal(s);for(const[i,e]of this.subscriptions)this.subscriptions.set(i,e.filter(r=>r.id!==s))}unsubscribeGlobal(s){this.globalSubscriptions=this.globalSubscriptions.filter(i=>i.id!==s)}get subscriptionsCount(){let s=0;return this.subscriptions.forEach(i=>{s+=i.length}),s+=this.globalSubscriptions.length,s}}function n(){return u.useRef(new b).current}function c(t,s,i=[]){const e=u.useMemo(()=>t instanceof b?t:t.instance,[t]),r=u.useMemo(()=>e.makeId("id"in t?t.id:void 0),[e]);u.useEffect(()=>(e.subscribeMany(r,s),()=>{e.unsubscribe(r)}),[e,r,...i])}function l(t,s,i=[]){const e=u.useMemo(()=>t instanceof b?t:t.instance,[t]),r=u.useMemo(()=>e.makeId("id"in t?t.id:void 0),[e]);u.useEffect(()=>(e.subscribeAll(r,s),()=>{e.unsubscribeGlobal(r)}),[e,r,...i])}exports.Siggn=b;exports.useSiggn=n;exports.useSubscribe=c;exports.useSubscribeAll=l;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react");class t{nextId=0;subscriptions;globalSubscriptions;middlewares;constructor(){this.subscriptions=new Map,this.globalSubscriptions=[],this.middlewares=[]}use(s){this.middlewares.push(s)}createClone(){return new t}makeId(s){return s??`sub_${(this.nextId++).toString(36)}`}make(s){return{subscribe:(e,u)=>{this.subscribe(s,e,u)},unsubscribe:()=>{this.unsubscribe(s)},subscribeMany:e=>{this.subscribeMany(s,e)},subscribeAll:e=>{this.subscribeAll(s,e)}}}subscribeMany(s,e){e((u,b)=>this.subscribe(s,u,b))}subscribe(s,e,u){this.subscriptions.has(e)||this.subscriptions.set(e,[]),this.subscriptions.get(e)?.push({id:s,ref:u})}subscribeAll(s,e){this.globalSubscriptions.push({id:s,ref:e})}publish(s){this.globalSubscriptions.forEach(e=>{e.ref(s)}),this.subscriptions.has(s.type)&&this.subscriptions.get(s.type)?.forEach(e=>{e.ref(s)})}unsubscribe(s){this.unsubscribeGlobal(s);for(const[e,u]of this.subscriptions)this.subscriptions.set(e,u.filter(b=>b.id!==s))}unsubscribeGlobal(s){this.globalSubscriptions=this.globalSubscriptions.filter(e=>e.id!==s)}}function n(){const[i]=r.useState(new t);return i}function a(i,s,e=[]){const u=r.useMemo(()=>i instanceof t?i:i.instance,[i]),b=r.useMemo(()=>u.makeId("id"in i?i.id:void 0),[u]);r.useEffect(()=>(u.subscribeMany(b,s),()=>{u.unsubscribe(b)}),[u,b,...e])}function l(i,s,e,u=[]){const b=r.useMemo(()=>i instanceof t?i:i.instance,[i]),c=r.useMemo(()=>b.makeId("id"in i?i.id:void 0),[b]);r.useEffect(()=>(b.subscribe(c,s,e),()=>{b.unsubscribe(c)}),[b,c,...u])}function o(i,s,e=[]){const u=r.useMemo(()=>i instanceof t?i:i.instance,[i]),b=r.useMemo(()=>u.makeId("id"in i?i.id:void 0),[u]);r.useEffect(()=>(u.subscribeAll(b,s),()=>{u.unsubscribeGlobal(b)}),[u,b,...e])}exports.Siggn=t;exports.useSiggn=n;exports.useSubscribe=l;exports.useSubscribeAll=o;exports.useSubscribeMany=a;
2
2
  //# sourceMappingURL=index.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs.js","sources":["../../core/dist/index.es.js","../src/hooks.ts"],"sourcesContent":["class e {\n nextId = 0;\n subscriptions;\n globalSubscriptions = [];\n /**\n * A FinalizationRegistry to automatically unregister specific subscriptions\n * when the subscribed callback function is garbage collected.\n */\n registry = new FinalizationRegistry((s) => {\n this.unsubscribe(s);\n });\n /**\n * A FinalizationRegistry to automatically unregister global subscriptions\n * when the subscribed callback function is garbage collected.\n */\n registryGlobal = new FinalizationRegistry((s) => {\n this.unsubscribeGlobal(s);\n });\n /**\n * Creates a new Siggn instance.\n * @category Lifecycle\n * @since 0.0.5\n */\n constructor() {\n this.subscriptions = /* @__PURE__ */ new Map();\n }\n /**\n * Creates a new, independent `Siggn` instance that inherits the message\n * types of its parent and adds new ones.\n *\n * @template C The new message types to add.\n * @returns A new `Siggn` instance with combined message types.\n * @category Lifecycle\n * @since 0.0.5\n * @example\n * \n ```typescript\n * const baseSiggn = new Siggn<{ type: 'A' }>();\n * const childSiggn = baseSiggn.createClone<{ type: 'B' }>();\n * // childSiggn can now publish and subscribe to types 'A' and 'B'.\n * ```\n */\n createClone() {\n return new e();\n }\n /**\n * Generates a unique ID for a subscriber.\n * If an ID is provided, it will be used; otherwise, a new one is generated.\n *\n * @param id An optional ID to use.\n * @returns A unique subscriber ID.\n * @category Utilities\n * @since 0.0.5\n * @example\n * \n ```typescript\n * const siggn = new Siggn();\n * const id1 = siggn.makeId(); // e.g., \"sub_0\"\n * const id2 = siggn.makeId('custom-id'); // \"custom-id\"\n * ```\n */\n makeId(s) {\n return s ?? `sub_${(this.nextId++).toString(36)}`;\n }\n /**\n * Creates a subscription helper object that is pre-configured with a\n * specific subscriber ID. This simplifies managing multiple subscriptions\n * for a single component or service.\n *\n * @param id The subscriber ID to use for all subscriptions.\n * @returns An object with `subscribe`, `unsubscribe`, `subscribeMany`, and `subscribeAll` methods.\n * @category Subscription\n * @since 0.0.5\n * @example\n * \n ```typescript\n * const siggn = new Siggn<{ type: 'event' }>();\n * const component = siggn.make('my-component');\n * component.subscribe('event', () => console.log('event received!'));\n * component.unsubscribe();\n * ```\n */\n make(s) {\n return {\n subscribe: (i, t) => {\n this.subscribe(s, i, t);\n },\n unsubscribe: () => {\n this.unsubscribe(s);\n },\n subscribeMany: (i) => {\n this.subscribeMany(s, i);\n },\n subscribeAll: (i) => {\n this.subscribeAll(s, i);\n }\n };\n }\n /**\n * Subscribes to multiple message types using a single subscriber ID.\n *\n * @param id The subscriber ID.\n * @param setup A function that receives a `subscribe` helper to register callbacks.\n * @category Subscription\n * @since 0.0.5\n * @example\n * \n ```typescript\n * const siggn = new Siggn<{ type: 'A' } | { type: 'B' }>();\n * siggn.subscribeMany('subscriber-1', (subscribe) => {\n * subscribe('A', () => console.log('A received'));\n * subscribe('B', () => console.log('B received'));\n * });\n * ```\n */\n subscribeMany(s, i) {\n i((t, r) => this.subscribe(s, t, r));\n }\n /**\n * Subscribes to a specific message type.\n *\n * @param id The subscriber ID.\n * @param type The message type to subscribe to.\n * @param callback The function to call when a message of the specified type is published.\n * @category Subscription\n * @since 0.0.5\n * @example\n * \n ```typescript\n * const siggn = new Siggn<{ type: 'my-event', payload: string }>();\n * siggn.subscribe('subscriber-1', 'my-event', (msg) => {\n * console.log(msg.payload);\n * });\n * ```\n */\n subscribe(s, i, t) {\n this.subscriptions.has(i) || this.subscriptions.set(i, []), this.registry.register(t, s), this.subscriptions.get(i)?.push({ id: s, ref: new WeakRef(t) });\n }\n /**\n * Subscribes to all message types. The callback will be invoked for every\n * message published on the bus.\n *\n * @param id The subscriber ID.\n * @param callback The function to call for any message.\n * @category Subscription\n * @since 0.0.5\n * @example\n * \n ```typescript\n * const siggn = new Siggn<{ type: 'A' } | { type: 'B' }>();\n * siggn.subscribeAll('logger', (msg) => {\n * console.log(`Received message of type: ${msg.type}`);\n * });\n * ```\n */\n subscribeAll(s, i) {\n this.registryGlobal.register(i, s), this.globalSubscriptions.push({ id: s, ref: new WeakRef(i) });\n }\n /**\n * Publishes a message to all relevant subscribers.\n *\n * @param msg The message to publish.\n * @category Publishing\n * @since 0.0.5\n * @example\n * \n ```typescript\n * const siggn = new Siggn<{ type: 'my-event' }>();\n * siggn.subscribe('sub-1', 'my-event', () => console.log('received'));\n * siggn.publish({ type: 'my-event' }); // \"received\"\n * ```\n */\n publish(s) {\n this.globalSubscriptions.forEach((i) => {\n const t = i.ref.deref();\n if (!t) {\n this.unsubscribeGlobal(i.id);\n return;\n }\n t(s);\n }), this.subscriptions.has(s.type) && this.subscriptions.get(s.type)?.forEach((i) => {\n const t = i.ref.deref();\n if (!t) {\n this.unsubscribe(i.id);\n return;\n }\n t(s);\n });\n }\n /**\n * Removes all subscriptions (both specific and global) for a given\n * subscriber ID.\n *\n * @param id The subscriber ID to unsubscribe.\n * @category Subscription\n * @since 0.0.5\n * @example\n * \n ```typescript\n * const siggn = new Siggn<{ type: 'my-event' }>();\n * siggn.subscribe('sub-1', 'my-event', () => console.log('received'));\n * siggn.unsubscribe('sub-1');\n * siggn.publish({ type: 'my-event' }); // (nothing is logged)\n * ```\n */\n unsubscribe(s) {\n this.unsubscribeGlobal(s);\n for (const [i, t] of this.subscriptions)\n this.subscriptions.set(\n i,\n t.filter((r) => r.id !== s)\n );\n }\n /**\n * Removes a global subscription for a given subscriber ID.\n *\n * @param id The subscriber ID to unsubscribe.\n * @category Subscription\n * @since 0.0.5\n * @example\n * \n ```typescript\n * const siggn = new Siggn<{ type: 'my-event' }>();\n * siggn.subscribeAll('logger', console.log);\n * siggn.unsubscribeGlobal('logger');\n * siggn.publish({ type: 'my-event' }); // (nothing is logged)\n * ```\n */\n unsubscribeGlobal(s) {\n this.globalSubscriptions = this.globalSubscriptions.filter((i) => i.id !== s);\n }\n /**\n * Returns the total number of subscriptions (both specific and global).\n *\n * @category Subscription\n * @since 0.1.0\n * @example\n * \n ```typescript\n * const siggn = new Siggn<{ type: 'my-event' }>();\n * siggn.subscribe('sub-1', 'my-event', () => {});\n * siggn.subscribeAll('logger', () => {});\n * console.log(siggn.subscriptionsCount); // 2\n * ```\n */\n get subscriptionsCount() {\n let s = 0;\n return this.subscriptions.forEach((i) => {\n s += i.length;\n }), s += this.globalSubscriptions.length, s;\n }\n}\nexport {\n e as Siggn\n};\n//# sourceMappingURL=index.es.js.map\n","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":["e","t","useSiggn","useRef","Siggn","useSubscribe","options","setup","deps","instance","useMemo","id","useEffect","useSubscribeAll","callback"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs.js","sources":["../../core/dist/index.es.js","../src/hooks.ts"],"sourcesContent":["class r {\n nextId = 0;\n subscriptions;\n globalSubscriptions;\n middlewares;\n /**\n * Creates a new Siggn instance.\n * @category Lifecycle\n * @since 0.0.5\n */\n constructor() {\n this.subscriptions = /* @__PURE__ */ new Map(), this.globalSubscriptions = [], this.middlewares = [];\n }\n use(s) {\n this.middlewares.push(s);\n }\n /**\n * Creates a new, independent `Siggn` instance that inherits the message\n * types of its parent and adds new ones.\n *\n * @template C The new message types to add.\n * @returns A new `Siggn` instance with combined message types.\n * @category Lifecycle\n * @since 0.0.5\n * @example\n * \n ```typescript\n * const baseSiggn = new Siggn<{ type: 'A' }>();\n * const childSiggn = baseSiggn.createClone<{ type: 'B' }>();\n * // childSiggn can now publish and subscribe to types 'A' and 'B'.\n * ```\n */\n createClone() {\n return new r();\n }\n /**\n * Generates a unique ID for a subscriber.\n * If an ID is provided, it will be used; otherwise, a new one is generated.\n *\n * @param id An optional ID to use.\n * @returns A unique subscriber ID.\n * @category Utilities\n * @since 0.0.5\n * @example\n * \n ```typescript\n * const siggn = new Siggn();\n * const id1 = siggn.makeId(); // e.g., \"sub_0\"\n * const id2 = siggn.makeId('custom-id'); // \"custom-id\"\n * ```\n */\n makeId(s) {\n return s ?? `sub_${(this.nextId++).toString(36)}`;\n }\n /**\n * Creates a subscription helper object that is pre-configured with a\n * specific subscriber ID. This simplifies managing multiple subscriptions\n * for a single component or service.\n *\n * @param id The subscriber ID to use for all subscriptions.\n * @returns An object with `subscribe`, `unsubscribe`, `subscribeMany`, and `subscribeAll` methods.\n * @category Subscription\n * @since 0.0.5\n * @example\n * \n ```typescript\n * const siggn = new Siggn<{ type: 'event' }>();\n * const component = siggn.make('my-component');\n * component.subscribe('event', () => console.log('event received!'));\n * component.unsubscribe();\n * ```\n */\n make(s) {\n return {\n subscribe: (i, t) => {\n this.subscribe(s, i, t);\n },\n unsubscribe: () => {\n this.unsubscribe(s);\n },\n subscribeMany: (i) => {\n this.subscribeMany(s, i);\n },\n subscribeAll: (i) => {\n this.subscribeAll(s, i);\n }\n };\n }\n /**\n * Subscribes to multiple message types using a single subscriber ID.\n *\n * @param id The subscriber ID.\n * @param setup A function that receives a `subscribe` helper to register callbacks.\n * @category Subscription\n * @since 0.0.5\n * @example\n * \n ```typescript\n * const siggn = new Siggn<{ type: 'A' } | { type: 'B' }>();\n * siggn.subscribeMany('subscriber-1', (subscribe) => {\n * subscribe('A', () => console.log('A received'));\n * subscribe('B', () => console.log('B received'));\n * });\n * ```\n */\n subscribeMany(s, i) {\n i((t, b) => this.subscribe(s, t, b));\n }\n /**\n * Subscribes to a specific message type.\n *\n * @param id The subscriber ID.\n * @param type The message type to subscribe to.\n * @param callback The function to call when a message of the specified type is published.\n * @category Subscription\n * @since 0.0.5\n * @example\n * \n ```typescript\n * const siggn = new Siggn<{ type: 'my-event', payload: string }>();\n * siggn.subscribe('subscriber-1', 'my-event', (msg) => {\n * console.log(msg.payload);\n * });\n * ```\n */\n subscribe(s, i, t) {\n this.subscriptions.has(i) || this.subscriptions.set(i, []), this.subscriptions.get(i)?.push({ id: s, ref: t });\n }\n /**\n * Subscribes to all message types. The callback will be invoked for every\n * message published on the bus.\n *\n * @param id The subscriber ID.\n * @param callback The function to call for any message.\n * @category Subscription\n * @since 0.0.5\n * @example\n * \n ```typescript\n * const siggn = new Siggn<{ type: 'A' } | { type: 'B' }>();\n * siggn.subscribeAll('logger', (msg) => {\n * console.log(`Received message of type: ${msg.type}`);\n * });\n * ```\n */\n subscribeAll(s, i) {\n this.globalSubscriptions.push({ id: s, ref: i });\n }\n /**\n * Publishes a message to all relevant subscribers.\n *\n * @param msg The message to publish.\n * @category Publishing\n * @since 0.0.5\n * @example\n * \n ```typescript\n * const siggn = new Siggn<{ type: 'my-event' }>();\n * siggn.subscribe('sub-1', 'my-event', () => console.log('received'));\n * siggn.publish({ type: 'my-event' }); // \"received\"\n * ```\n */\n publish(s) {\n this.globalSubscriptions.forEach((i) => {\n i.ref(s);\n }), this.subscriptions.has(s.type) && this.subscriptions.get(s.type)?.forEach((i) => {\n i.ref(s);\n });\n }\n /**\n * Removes all subscriptions (both specific and global) for a given\n * subscriber ID.\n *\n * @param id The subscriber ID to unsubscribe.\n * @category Subscription\n * @since 0.0.5\n * @example\n * \n ```typescript\n * const siggn = new Siggn<{ type: 'my-event' }>();\n * siggn.subscribe('sub-1', 'my-event', () => console.log('received'));\n * siggn.unsubscribe('sub-1');\n * siggn.publish({ type: 'my-event' }); // (nothing is logged)\n * ```\n */\n unsubscribe(s) {\n this.unsubscribeGlobal(s);\n for (const [i, t] of this.subscriptions)\n this.subscriptions.set(\n i,\n t.filter((b) => b.id !== s)\n );\n }\n /**\n * Removes a global subscription for a given subscriber ID.\n *\n * @param id The subscriber ID to unsubscribe.\n * @category Subscription\n * @since 0.0.5\n * @example\n * \n ```typescript\n * const siggn = new Siggn<{ type: 'my-event' }>();\n * siggn.subscribeAll('logger', console.log);\n * siggn.unsubscribeGlobal('logger');\n * siggn.publish({ type: 'my-event' }); // (nothing is logged)\n * ```\n */\n unsubscribeGlobal(s) {\n this.globalSubscriptions = this.globalSubscriptions.filter((i) => i.id !== s);\n }\n}\nexport {\n r as Siggn\n};\n//# sourceMappingURL=index.es.js.map\n","import { type Msg, Siggn } from '@siggn/core';\nimport type { SubscriptionOptions } from 'packages/react/src/types';\nimport { useEffect, useMemo, useState, 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] = useState(new Siggn<T>());\n return siggn;\n}\n\n/**\n * Subscribes to multiple 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 * useSubscribeMany(siggn, (subscribe) => {\n * subscribe('user-created', (msg) => console.log(msg.name));\n * subscribe('user-updated', (msg) => console.log(msg.name));\n * });\n * // ...\n * }\n * ```\n */\nexport function useSubscribeMany<M extends Msg>(\n options: SubscriptionOptions<M>,\n setup: (\n subscribe: <T extends M['type']>(\n type: T,\n callback: (msg: Extract<M, { type: T }>) => 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 a single message and automatically unsubscribe 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, 'user-created', (msg) => console.log(msg.name));\n * // ...\n * }\n * ```\n */\nexport function useSubscribe<M extends Msg, T extends M['type']>(\n options: SubscriptionOptions<M>,\n type: T,\n callback: (msg: Extract<M, { type: 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.subscribe(id, type, callback);\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":["r","i","t","useSiggn","siggn","useState","Siggn","useSubscribeMany","options","setup","deps","instance","useMemo","id","useEffect","useSubscribe","type","callback","useSubscribeAll"],"mappings":"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"}
package/dist/index.es.js CHANGED
@@ -1,29 +1,19 @@
1
- import { useRef as c, useMemo as b, useEffect as u } from "react";
2
- class n {
1
+ import { useState as a, useMemo as u, useEffect as c } from "react";
2
+ class t {
3
3
  nextId = 0;
4
4
  subscriptions;
5
- globalSubscriptions = [];
6
- /**
7
- * A FinalizationRegistry to automatically unregister specific subscriptions
8
- * when the subscribed callback function is garbage collected.
9
- */
10
- registry = new FinalizationRegistry((s) => {
11
- this.unsubscribe(s);
12
- });
13
- /**
14
- * A FinalizationRegistry to automatically unregister global subscriptions
15
- * when the subscribed callback function is garbage collected.
16
- */
17
- registryGlobal = new FinalizationRegistry((s) => {
18
- this.unsubscribeGlobal(s);
19
- });
5
+ globalSubscriptions;
6
+ middlewares;
20
7
  /**
21
8
  * Creates a new Siggn instance.
22
9
  * @category Lifecycle
23
10
  * @since 0.0.5
24
11
  */
25
12
  constructor() {
26
- this.subscriptions = /* @__PURE__ */ new Map();
13
+ this.subscriptions = /* @__PURE__ */ new Map(), this.globalSubscriptions = [], this.middlewares = [];
14
+ }
15
+ use(s) {
16
+ this.middlewares.push(s);
27
17
  }
28
18
  /**
29
19
  * Creates a new, independent `Siggn` instance that inherits the message
@@ -42,7 +32,7 @@ class n {
42
32
  * ```
43
33
  */
44
34
  createClone() {
45
- return new n();
35
+ return new t();
46
36
  }
47
37
  /**
48
38
  * Generates a unique ID for a subscriber.
@@ -83,8 +73,8 @@ class n {
83
73
  */
84
74
  make(s) {
85
75
  return {
86
- subscribe: (i, e) => {
87
- this.subscribe(s, i, e);
76
+ subscribe: (i, b) => {
77
+ this.subscribe(s, i, b);
88
78
  },
89
79
  unsubscribe: () => {
90
80
  this.unsubscribe(s);
@@ -115,7 +105,7 @@ class n {
115
105
  * ```
116
106
  */
117
107
  subscribeMany(s, i) {
118
- i((e, r) => this.subscribe(s, e, r));
108
+ i((b, r) => this.subscribe(s, b, r));
119
109
  }
120
110
  /**
121
111
  * Subscribes to a specific message type.
@@ -134,8 +124,8 @@ class n {
134
124
  * });
135
125
  * ```
136
126
  */
137
- subscribe(s, i, e) {
138
- this.subscriptions.has(i) || this.subscriptions.set(i, []), this.registry.register(e, s), this.subscriptions.get(i)?.push({ id: s, ref: new WeakRef(e) });
127
+ subscribe(s, i, b) {
128
+ this.subscriptions.has(i) || this.subscriptions.set(i, []), this.subscriptions.get(i)?.push({ id: s, ref: b });
139
129
  }
140
130
  /**
141
131
  * Subscribes to all message types. The callback will be invoked for every
@@ -155,7 +145,7 @@ class n {
155
145
  * ```
156
146
  */
157
147
  subscribeAll(s, i) {
158
- this.registryGlobal.register(i, s), this.globalSubscriptions.push({ id: s, ref: new WeakRef(i) });
148
+ this.globalSubscriptions.push({ id: s, ref: i });
159
149
  }
160
150
  /**
161
151
  * Publishes a message to all relevant subscribers.
@@ -173,19 +163,9 @@ class n {
173
163
  */
174
164
  publish(s) {
175
165
  this.globalSubscriptions.forEach((i) => {
176
- const e = i.ref.deref();
177
- if (!e) {
178
- this.unsubscribeGlobal(i.id);
179
- return;
180
- }
181
- e(s);
166
+ i.ref(s);
182
167
  }), this.subscriptions.has(s.type) && this.subscriptions.get(s.type)?.forEach((i) => {
183
- const e = i.ref.deref();
184
- if (!e) {
185
- this.unsubscribe(i.id);
186
- return;
187
- }
188
- e(s);
168
+ i.ref(s);
189
169
  });
190
170
  }
191
171
  /**
@@ -206,10 +186,10 @@ class n {
206
186
  */
207
187
  unsubscribe(s) {
208
188
  this.unsubscribeGlobal(s);
209
- for (const [i, e] of this.subscriptions)
189
+ for (const [i, b] of this.subscriptions)
210
190
  this.subscriptions.set(
211
191
  i,
212
- e.filter((r) => r.id !== s)
192
+ b.filter((r) => r.id !== s)
213
193
  );
214
194
  }
215
195
  /**
@@ -230,52 +210,43 @@ class n {
230
210
  unsubscribeGlobal(s) {
231
211
  this.globalSubscriptions = this.globalSubscriptions.filter((i) => i.id !== s);
232
212
  }
233
- /**
234
- * Returns the total number of subscriptions (both specific and global).
235
- *
236
- * @category Subscription
237
- * @since 0.1.0
238
- * @example
239
- *
240
- ```typescript
241
- * const siggn = new Siggn<{ type: 'my-event' }>();
242
- * siggn.subscribe('sub-1', 'my-event', () => {});
243
- * siggn.subscribeAll('logger', () => {});
244
- * console.log(siggn.subscriptionsCount); // 2
245
- * ```
246
- */
247
- get subscriptionsCount() {
248
- let s = 0;
249
- return this.subscriptions.forEach((i) => {
250
- s += i.length;
251
- }), s += this.globalSubscriptions.length, s;
252
- }
253
213
  }
254
- function a() {
255
- return c(new n()).current;
214
+ function h() {
215
+ const [e] = a(new t());
216
+ return e;
217
+ }
218
+ function d(e, s, i = []) {
219
+ const b = u(
220
+ () => e instanceof t ? e : e.instance,
221
+ [e]
222
+ ), r = u(() => b.makeId("id" in e ? e.id : void 0), [b]);
223
+ c(() => (b.subscribeMany(r, s), () => {
224
+ b.unsubscribe(r);
225
+ }), [b, r, ...i]);
256
226
  }
257
- function o(t, s, i = []) {
258
- const e = b(
259
- () => t instanceof n ? t : t.instance,
260
- [t]
261
- ), r = b(() => e.makeId("id" in t ? t.id : void 0), [e]);
262
- u(() => (e.subscribeMany(r, s), () => {
263
- e.unsubscribe(r);
264
- }), [e, r, ...i]);
227
+ function o(e, s, i, b = []) {
228
+ const r = u(
229
+ () => e instanceof t ? e : e.instance,
230
+ [e]
231
+ ), n = u(() => r.makeId("id" in e ? e.id : void 0), [r]);
232
+ c(() => (r.subscribe(n, s, i), () => {
233
+ r.unsubscribe(n);
234
+ }), [r, n, ...b]);
265
235
  }
266
- function h(t, s, i = []) {
267
- const e = b(
268
- () => t instanceof n ? t : t.instance,
269
- [t]
270
- ), r = b(() => e.makeId("id" in t ? t.id : void 0), [e]);
271
- u(() => (e.subscribeAll(r, s), () => {
272
- e.unsubscribeGlobal(r);
273
- }), [e, r, ...i]);
236
+ function f(e, s, i = []) {
237
+ const b = u(
238
+ () => e instanceof t ? e : e.instance,
239
+ [e]
240
+ ), r = u(() => b.makeId("id" in e ? e.id : void 0), [b]);
241
+ c(() => (b.subscribeAll(r, s), () => {
242
+ b.unsubscribeGlobal(r);
243
+ }), [b, r, ...i]);
274
244
  }
275
245
  export {
276
- n as Siggn,
277
- a as useSiggn,
246
+ t as Siggn,
247
+ h as useSiggn,
278
248
  o as useSubscribe,
279
- h as useSubscribeAll
249
+ f as useSubscribeAll,
250
+ d as useSubscribeMany
280
251
  };
281
252
  //# sourceMappingURL=index.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.es.js","sources":["../../core/dist/index.es.js","../src/hooks.ts"],"sourcesContent":["class e {\n nextId = 0;\n subscriptions;\n globalSubscriptions = [];\n /**\n * A FinalizationRegistry to automatically unregister specific subscriptions\n * when the subscribed callback function is garbage collected.\n */\n registry = new FinalizationRegistry((s) => {\n this.unsubscribe(s);\n });\n /**\n * A FinalizationRegistry to automatically unregister global subscriptions\n * when the subscribed callback function is garbage collected.\n */\n registryGlobal = new FinalizationRegistry((s) => {\n this.unsubscribeGlobal(s);\n });\n /**\n * Creates a new Siggn instance.\n * @category Lifecycle\n * @since 0.0.5\n */\n constructor() {\n this.subscriptions = /* @__PURE__ */ new Map();\n }\n /**\n * Creates a new, independent `Siggn` instance that inherits the message\n * types of its parent and adds new ones.\n *\n * @template C The new message types to add.\n * @returns A new `Siggn` instance with combined message types.\n * @category Lifecycle\n * @since 0.0.5\n * @example\n * \n ```typescript\n * const baseSiggn = new Siggn<{ type: 'A' }>();\n * const childSiggn = baseSiggn.createClone<{ type: 'B' }>();\n * // childSiggn can now publish and subscribe to types 'A' and 'B'.\n * ```\n */\n createClone() {\n return new e();\n }\n /**\n * Generates a unique ID for a subscriber.\n * If an ID is provided, it will be used; otherwise, a new one is generated.\n *\n * @param id An optional ID to use.\n * @returns A unique subscriber ID.\n * @category Utilities\n * @since 0.0.5\n * @example\n * \n ```typescript\n * const siggn = new Siggn();\n * const id1 = siggn.makeId(); // e.g., \"sub_0\"\n * const id2 = siggn.makeId('custom-id'); // \"custom-id\"\n * ```\n */\n makeId(s) {\n return s ?? `sub_${(this.nextId++).toString(36)}`;\n }\n /**\n * Creates a subscription helper object that is pre-configured with a\n * specific subscriber ID. This simplifies managing multiple subscriptions\n * for a single component or service.\n *\n * @param id The subscriber ID to use for all subscriptions.\n * @returns An object with `subscribe`, `unsubscribe`, `subscribeMany`, and `subscribeAll` methods.\n * @category Subscription\n * @since 0.0.5\n * @example\n * \n ```typescript\n * const siggn = new Siggn<{ type: 'event' }>();\n * const component = siggn.make('my-component');\n * component.subscribe('event', () => console.log('event received!'));\n * component.unsubscribe();\n * ```\n */\n make(s) {\n return {\n subscribe: (i, t) => {\n this.subscribe(s, i, t);\n },\n unsubscribe: () => {\n this.unsubscribe(s);\n },\n subscribeMany: (i) => {\n this.subscribeMany(s, i);\n },\n subscribeAll: (i) => {\n this.subscribeAll(s, i);\n }\n };\n }\n /**\n * Subscribes to multiple message types using a single subscriber ID.\n *\n * @param id The subscriber ID.\n * @param setup A function that receives a `subscribe` helper to register callbacks.\n * @category Subscription\n * @since 0.0.5\n * @example\n * \n ```typescript\n * const siggn = new Siggn<{ type: 'A' } | { type: 'B' }>();\n * siggn.subscribeMany('subscriber-1', (subscribe) => {\n * subscribe('A', () => console.log('A received'));\n * subscribe('B', () => console.log('B received'));\n * });\n * ```\n */\n subscribeMany(s, i) {\n i((t, r) => this.subscribe(s, t, r));\n }\n /**\n * Subscribes to a specific message type.\n *\n * @param id The subscriber ID.\n * @param type The message type to subscribe to.\n * @param callback The function to call when a message of the specified type is published.\n * @category Subscription\n * @since 0.0.5\n * @example\n * \n ```typescript\n * const siggn = new Siggn<{ type: 'my-event', payload: string }>();\n * siggn.subscribe('subscriber-1', 'my-event', (msg) => {\n * console.log(msg.payload);\n * });\n * ```\n */\n subscribe(s, i, t) {\n this.subscriptions.has(i) || this.subscriptions.set(i, []), this.registry.register(t, s), this.subscriptions.get(i)?.push({ id: s, ref: new WeakRef(t) });\n }\n /**\n * Subscribes to all message types. The callback will be invoked for every\n * message published on the bus.\n *\n * @param id The subscriber ID.\n * @param callback The function to call for any message.\n * @category Subscription\n * @since 0.0.5\n * @example\n * \n ```typescript\n * const siggn = new Siggn<{ type: 'A' } | { type: 'B' }>();\n * siggn.subscribeAll('logger', (msg) => {\n * console.log(`Received message of type: ${msg.type}`);\n * });\n * ```\n */\n subscribeAll(s, i) {\n this.registryGlobal.register(i, s), this.globalSubscriptions.push({ id: s, ref: new WeakRef(i) });\n }\n /**\n * Publishes a message to all relevant subscribers.\n *\n * @param msg The message to publish.\n * @category Publishing\n * @since 0.0.5\n * @example\n * \n ```typescript\n * const siggn = new Siggn<{ type: 'my-event' }>();\n * siggn.subscribe('sub-1', 'my-event', () => console.log('received'));\n * siggn.publish({ type: 'my-event' }); // \"received\"\n * ```\n */\n publish(s) {\n this.globalSubscriptions.forEach((i) => {\n const t = i.ref.deref();\n if (!t) {\n this.unsubscribeGlobal(i.id);\n return;\n }\n t(s);\n }), this.subscriptions.has(s.type) && this.subscriptions.get(s.type)?.forEach((i) => {\n const t = i.ref.deref();\n if (!t) {\n this.unsubscribe(i.id);\n return;\n }\n t(s);\n });\n }\n /**\n * Removes all subscriptions (both specific and global) for a given\n * subscriber ID.\n *\n * @param id The subscriber ID to unsubscribe.\n * @category Subscription\n * @since 0.0.5\n * @example\n * \n ```typescript\n * const siggn = new Siggn<{ type: 'my-event' }>();\n * siggn.subscribe('sub-1', 'my-event', () => console.log('received'));\n * siggn.unsubscribe('sub-1');\n * siggn.publish({ type: 'my-event' }); // (nothing is logged)\n * ```\n */\n unsubscribe(s) {\n this.unsubscribeGlobal(s);\n for (const [i, t] of this.subscriptions)\n this.subscriptions.set(\n i,\n t.filter((r) => r.id !== s)\n );\n }\n /**\n * Removes a global subscription for a given subscriber ID.\n *\n * @param id The subscriber ID to unsubscribe.\n * @category Subscription\n * @since 0.0.5\n * @example\n * \n ```typescript\n * const siggn = new Siggn<{ type: 'my-event' }>();\n * siggn.subscribeAll('logger', console.log);\n * siggn.unsubscribeGlobal('logger');\n * siggn.publish({ type: 'my-event' }); // (nothing is logged)\n * ```\n */\n unsubscribeGlobal(s) {\n this.globalSubscriptions = this.globalSubscriptions.filter((i) => i.id !== s);\n }\n /**\n * Returns the total number of subscriptions (both specific and global).\n *\n * @category Subscription\n * @since 0.1.0\n * @example\n * \n ```typescript\n * const siggn = new Siggn<{ type: 'my-event' }>();\n * siggn.subscribe('sub-1', 'my-event', () => {});\n * siggn.subscribeAll('logger', () => {});\n * console.log(siggn.subscriptionsCount); // 2\n * ```\n */\n get subscriptionsCount() {\n let s = 0;\n return this.subscriptions.forEach((i) => {\n s += i.length;\n }), s += this.globalSubscriptions.length, s;\n }\n}\nexport {\n e as Siggn\n};\n//# sourceMappingURL=index.es.js.map\n","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":["e","t","useSiggn","useRef","Siggn","useSubscribe","options","setup","deps","instance","useMemo","id","useEffect","useSubscribeAll","callback"],"mappings":"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"}
1
+ {"version":3,"file":"index.es.js","sources":["../../core/dist/index.es.js","../src/hooks.ts"],"sourcesContent":["class r {\n nextId = 0;\n subscriptions;\n globalSubscriptions;\n middlewares;\n /**\n * Creates a new Siggn instance.\n * @category Lifecycle\n * @since 0.0.5\n */\n constructor() {\n this.subscriptions = /* @__PURE__ */ new Map(), this.globalSubscriptions = [], this.middlewares = [];\n }\n use(s) {\n this.middlewares.push(s);\n }\n /**\n * Creates a new, independent `Siggn` instance that inherits the message\n * types of its parent and adds new ones.\n *\n * @template C The new message types to add.\n * @returns A new `Siggn` instance with combined message types.\n * @category Lifecycle\n * @since 0.0.5\n * @example\n * \n ```typescript\n * const baseSiggn = new Siggn<{ type: 'A' }>();\n * const childSiggn = baseSiggn.createClone<{ type: 'B' }>();\n * // childSiggn can now publish and subscribe to types 'A' and 'B'.\n * ```\n */\n createClone() {\n return new r();\n }\n /**\n * Generates a unique ID for a subscriber.\n * If an ID is provided, it will be used; otherwise, a new one is generated.\n *\n * @param id An optional ID to use.\n * @returns A unique subscriber ID.\n * @category Utilities\n * @since 0.0.5\n * @example\n * \n ```typescript\n * const siggn = new Siggn();\n * const id1 = siggn.makeId(); // e.g., \"sub_0\"\n * const id2 = siggn.makeId('custom-id'); // \"custom-id\"\n * ```\n */\n makeId(s) {\n return s ?? `sub_${(this.nextId++).toString(36)}`;\n }\n /**\n * Creates a subscription helper object that is pre-configured with a\n * specific subscriber ID. This simplifies managing multiple subscriptions\n * for a single component or service.\n *\n * @param id The subscriber ID to use for all subscriptions.\n * @returns An object with `subscribe`, `unsubscribe`, `subscribeMany`, and `subscribeAll` methods.\n * @category Subscription\n * @since 0.0.5\n * @example\n * \n ```typescript\n * const siggn = new Siggn<{ type: 'event' }>();\n * const component = siggn.make('my-component');\n * component.subscribe('event', () => console.log('event received!'));\n * component.unsubscribe();\n * ```\n */\n make(s) {\n return {\n subscribe: (i, t) => {\n this.subscribe(s, i, t);\n },\n unsubscribe: () => {\n this.unsubscribe(s);\n },\n subscribeMany: (i) => {\n this.subscribeMany(s, i);\n },\n subscribeAll: (i) => {\n this.subscribeAll(s, i);\n }\n };\n }\n /**\n * Subscribes to multiple message types using a single subscriber ID.\n *\n * @param id The subscriber ID.\n * @param setup A function that receives a `subscribe` helper to register callbacks.\n * @category Subscription\n * @since 0.0.5\n * @example\n * \n ```typescript\n * const siggn = new Siggn<{ type: 'A' } | { type: 'B' }>();\n * siggn.subscribeMany('subscriber-1', (subscribe) => {\n * subscribe('A', () => console.log('A received'));\n * subscribe('B', () => console.log('B received'));\n * });\n * ```\n */\n subscribeMany(s, i) {\n i((t, b) => this.subscribe(s, t, b));\n }\n /**\n * Subscribes to a specific message type.\n *\n * @param id The subscriber ID.\n * @param type The message type to subscribe to.\n * @param callback The function to call when a message of the specified type is published.\n * @category Subscription\n * @since 0.0.5\n * @example\n * \n ```typescript\n * const siggn = new Siggn<{ type: 'my-event', payload: string }>();\n * siggn.subscribe('subscriber-1', 'my-event', (msg) => {\n * console.log(msg.payload);\n * });\n * ```\n */\n subscribe(s, i, t) {\n this.subscriptions.has(i) || this.subscriptions.set(i, []), this.subscriptions.get(i)?.push({ id: s, ref: t });\n }\n /**\n * Subscribes to all message types. The callback will be invoked for every\n * message published on the bus.\n *\n * @param id The subscriber ID.\n * @param callback The function to call for any message.\n * @category Subscription\n * @since 0.0.5\n * @example\n * \n ```typescript\n * const siggn = new Siggn<{ type: 'A' } | { type: 'B' }>();\n * siggn.subscribeAll('logger', (msg) => {\n * console.log(`Received message of type: ${msg.type}`);\n * });\n * ```\n */\n subscribeAll(s, i) {\n this.globalSubscriptions.push({ id: s, ref: i });\n }\n /**\n * Publishes a message to all relevant subscribers.\n *\n * @param msg The message to publish.\n * @category Publishing\n * @since 0.0.5\n * @example\n * \n ```typescript\n * const siggn = new Siggn<{ type: 'my-event' }>();\n * siggn.subscribe('sub-1', 'my-event', () => console.log('received'));\n * siggn.publish({ type: 'my-event' }); // \"received\"\n * ```\n */\n publish(s) {\n this.globalSubscriptions.forEach((i) => {\n i.ref(s);\n }), this.subscriptions.has(s.type) && this.subscriptions.get(s.type)?.forEach((i) => {\n i.ref(s);\n });\n }\n /**\n * Removes all subscriptions (both specific and global) for a given\n * subscriber ID.\n *\n * @param id The subscriber ID to unsubscribe.\n * @category Subscription\n * @since 0.0.5\n * @example\n * \n ```typescript\n * const siggn = new Siggn<{ type: 'my-event' }>();\n * siggn.subscribe('sub-1', 'my-event', () => console.log('received'));\n * siggn.unsubscribe('sub-1');\n * siggn.publish({ type: 'my-event' }); // (nothing is logged)\n * ```\n */\n unsubscribe(s) {\n this.unsubscribeGlobal(s);\n for (const [i, t] of this.subscriptions)\n this.subscriptions.set(\n i,\n t.filter((b) => b.id !== s)\n );\n }\n /**\n * Removes a global subscription for a given subscriber ID.\n *\n * @param id The subscriber ID to unsubscribe.\n * @category Subscription\n * @since 0.0.5\n * @example\n * \n ```typescript\n * const siggn = new Siggn<{ type: 'my-event' }>();\n * siggn.subscribeAll('logger', console.log);\n * siggn.unsubscribeGlobal('logger');\n * siggn.publish({ type: 'my-event' }); // (nothing is logged)\n * ```\n */\n unsubscribeGlobal(s) {\n this.globalSubscriptions = this.globalSubscriptions.filter((i) => i.id !== s);\n }\n}\nexport {\n r as Siggn\n};\n//# sourceMappingURL=index.es.js.map\n","import { type Msg, Siggn } from '@siggn/core';\nimport type { SubscriptionOptions } from 'packages/react/src/types';\nimport { useEffect, useMemo, useState, 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] = useState(new Siggn<T>());\n return siggn;\n}\n\n/**\n * Subscribes to multiple 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 * useSubscribeMany(siggn, (subscribe) => {\n * subscribe('user-created', (msg) => console.log(msg.name));\n * subscribe('user-updated', (msg) => console.log(msg.name));\n * });\n * // ...\n * }\n * ```\n */\nexport function useSubscribeMany<M extends Msg>(\n options: SubscriptionOptions<M>,\n setup: (\n subscribe: <T extends M['type']>(\n type: T,\n callback: (msg: Extract<M, { type: T }>) => 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 a single message and automatically unsubscribe 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, 'user-created', (msg) => console.log(msg.name));\n * // ...\n * }\n * ```\n */\nexport function useSubscribe<M extends Msg, T extends M['type']>(\n options: SubscriptionOptions<M>,\n type: T,\n callback: (msg: Extract<M, { type: 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.subscribe(id, type, callback);\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":["r","t","b","useSiggn","siggn","useState","Siggn","useSubscribeMany","options","setup","deps","instance","useMemo","id","useEffect","useSubscribe","type","callback","useSubscribeAll"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@siggn/react",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "A lightweight type safe message bus system for React",
5
5
  "keywords": [
6
6
  "pub/sub",
@@ -58,7 +58,7 @@
58
58
  "react": ">=18 <20"
59
59
  },
60
60
  "dependencies": {
61
- "@siggn/core": "0.1.0"
61
+ "@siggn/core": "0.1.1"
62
62
  },
63
63
  "scripts": {
64
64
  "dev": "vite build --watch",