mvc-kit 2.12.5 → 2.13.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 (186) hide show
  1. package/agent-config/bin/postinstall.mjs +4 -3
  2. package/agent-config/bin/setup.mjs +5 -1
  3. package/agent-config/claude-code/agents/mvc-kit-architect.md +11 -8
  4. package/agent-config/claude-code/skills/guide/SKILL.md +20 -7
  5. package/agent-config/claude-code/skills/guide/patterns.md +12 -0
  6. package/agent-config/claude-code/skills/guide/recipes.md +510 -0
  7. package/agent-config/claude-code/skills/guide/testing.md +297 -0
  8. package/agent-config/claude-code/skills/review/SKILL.md +3 -13
  9. package/agent-config/claude-code/skills/review/checklist.md +30 -5
  10. package/agent-config/claude-code/skills/scaffold/SKILL.md +4 -13
  11. package/agent-config/lib/install-claude.mjs +84 -25
  12. package/dist/Channel.cjs +276 -300
  13. package/dist/Channel.cjs.map +1 -1
  14. package/dist/Channel.js +275 -299
  15. package/dist/Channel.js.map +1 -1
  16. package/dist/Collection.cjs +424 -504
  17. package/dist/Collection.cjs.map +1 -1
  18. package/dist/Collection.js +423 -503
  19. package/dist/Collection.js.map +1 -1
  20. package/dist/Controller.cjs +70 -67
  21. package/dist/Controller.cjs.map +1 -1
  22. package/dist/Controller.js +69 -66
  23. package/dist/Controller.js.map +1 -1
  24. package/dist/EventBus.cjs +77 -88
  25. package/dist/EventBus.cjs.map +1 -1
  26. package/dist/EventBus.js +76 -87
  27. package/dist/EventBus.js.map +1 -1
  28. package/dist/Feed.cjs +81 -77
  29. package/dist/Feed.cjs.map +1 -1
  30. package/dist/Feed.js +80 -76
  31. package/dist/Feed.js.map +1 -1
  32. package/dist/Model.cjs +181 -207
  33. package/dist/Model.cjs.map +1 -1
  34. package/dist/Model.js +179 -205
  35. package/dist/Model.js.map +1 -1
  36. package/dist/Pagination.cjs +75 -73
  37. package/dist/Pagination.cjs.map +1 -1
  38. package/dist/Pagination.js +74 -72
  39. package/dist/Pagination.js.map +1 -1
  40. package/dist/Pending.cjs +255 -287
  41. package/dist/Pending.cjs.map +1 -1
  42. package/dist/Pending.js +253 -285
  43. package/dist/Pending.js.map +1 -1
  44. package/dist/PersistentCollection.cjs +242 -285
  45. package/dist/PersistentCollection.cjs.map +1 -1
  46. package/dist/PersistentCollection.js +241 -284
  47. package/dist/PersistentCollection.js.map +1 -1
  48. package/dist/Resource.cjs +166 -174
  49. package/dist/Resource.cjs.map +1 -1
  50. package/dist/Resource.js +164 -172
  51. package/dist/Resource.js.map +1 -1
  52. package/dist/Selection.cjs +84 -94
  53. package/dist/Selection.cjs.map +1 -1
  54. package/dist/Selection.js +83 -93
  55. package/dist/Selection.js.map +1 -1
  56. package/dist/Service.cjs +54 -55
  57. package/dist/Service.cjs.map +1 -1
  58. package/dist/Service.js +53 -54
  59. package/dist/Service.js.map +1 -1
  60. package/dist/Sorting.cjs +102 -101
  61. package/dist/Sorting.cjs.map +1 -1
  62. package/dist/Sorting.js +102 -101
  63. package/dist/Sorting.js.map +1 -1
  64. package/dist/Trackable.cjs +112 -80
  65. package/dist/Trackable.cjs.map +1 -1
  66. package/dist/Trackable.js +111 -79
  67. package/dist/Trackable.js.map +1 -1
  68. package/dist/ViewModel.cjs +528 -576
  69. package/dist/ViewModel.cjs.map +1 -1
  70. package/dist/ViewModel.js +525 -573
  71. package/dist/ViewModel.js.map +1 -1
  72. package/dist/bindPublicMethods.cjs +43 -24
  73. package/dist/bindPublicMethods.cjs.map +1 -1
  74. package/dist/bindPublicMethods.js +43 -24
  75. package/dist/bindPublicMethods.js.map +1 -1
  76. package/dist/errors.cjs +67 -68
  77. package/dist/errors.cjs.map +1 -1
  78. package/dist/errors.js +68 -71
  79. package/dist/errors.js.map +1 -1
  80. package/dist/mvc-kit.cjs +44 -46
  81. package/dist/mvc-kit.js +5 -32
  82. package/dist/produceDraft.cjs +105 -95
  83. package/dist/produceDraft.cjs.map +1 -1
  84. package/dist/produceDraft.js +106 -97
  85. package/dist/produceDraft.js.map +1 -1
  86. package/dist/react/components/CardList.cjs +30 -40
  87. package/dist/react/components/CardList.cjs.map +1 -1
  88. package/dist/react/components/CardList.js +31 -41
  89. package/dist/react/components/CardList.js.map +1 -1
  90. package/dist/react/components/DataTable.cjs +146 -169
  91. package/dist/react/components/DataTable.cjs.map +1 -1
  92. package/dist/react/components/DataTable.js +147 -170
  93. package/dist/react/components/DataTable.js.map +1 -1
  94. package/dist/react/components/InfiniteScroll.cjs +51 -42
  95. package/dist/react/components/InfiniteScroll.cjs.map +1 -1
  96. package/dist/react/components/InfiniteScroll.js +52 -43
  97. package/dist/react/components/InfiniteScroll.js.map +1 -1
  98. package/dist/react/components/types.cjs +10 -6
  99. package/dist/react/components/types.cjs.map +1 -1
  100. package/dist/react/components/types.js +11 -9
  101. package/dist/react/components/types.js.map +1 -1
  102. package/dist/react/guards.cjs +10 -6
  103. package/dist/react/guards.cjs.map +1 -1
  104. package/dist/react/guards.js +11 -9
  105. package/dist/react/guards.js.map +1 -1
  106. package/dist/react/provider.cjs +23 -20
  107. package/dist/react/provider.cjs.map +1 -1
  108. package/dist/react/provider.js +23 -21
  109. package/dist/react/provider.js.map +1 -1
  110. package/dist/react/use-event-bus.cjs +24 -20
  111. package/dist/react/use-event-bus.cjs.map +1 -1
  112. package/dist/react/use-event-bus.js +24 -21
  113. package/dist/react/use-event-bus.js.map +1 -1
  114. package/dist/react/use-instance.cjs +43 -36
  115. package/dist/react/use-instance.cjs.map +1 -1
  116. package/dist/react/use-instance.js +43 -36
  117. package/dist/react/use-instance.js.map +1 -1
  118. package/dist/react/use-local.cjs +48 -64
  119. package/dist/react/use-local.cjs.map +1 -1
  120. package/dist/react/use-local.js +47 -63
  121. package/dist/react/use-local.js.map +1 -1
  122. package/dist/react/use-model.cjs +84 -98
  123. package/dist/react/use-model.cjs.map +1 -1
  124. package/dist/react/use-model.js +84 -100
  125. package/dist/react/use-model.js.map +1 -1
  126. package/dist/react/use-singleton.cjs +19 -23
  127. package/dist/react/use-singleton.cjs.map +1 -1
  128. package/dist/react/use-singleton.js +16 -20
  129. package/dist/react/use-singleton.js.map +1 -1
  130. package/dist/react/use-subscribe-only.cjs +28 -22
  131. package/dist/react/use-subscribe-only.cjs.map +1 -1
  132. package/dist/react/use-subscribe-only.js +28 -22
  133. package/dist/react/use-subscribe-only.js.map +1 -1
  134. package/dist/react/use-teardown.cjs +20 -19
  135. package/dist/react/use-teardown.cjs.map +1 -1
  136. package/dist/react/use-teardown.js +20 -19
  137. package/dist/react/use-teardown.js.map +1 -1
  138. package/dist/react-native/NativeCollection.cjs +98 -78
  139. package/dist/react-native/NativeCollection.cjs.map +1 -1
  140. package/dist/react-native/NativeCollection.js +97 -77
  141. package/dist/react-native/NativeCollection.js.map +1 -1
  142. package/dist/react-native.cjs +2 -4
  143. package/dist/react-native.js +1 -4
  144. package/dist/react.cjs +24 -26
  145. package/dist/react.js +1 -17
  146. package/dist/singleton.cjs +28 -22
  147. package/dist/singleton.cjs.map +1 -1
  148. package/dist/singleton.js +29 -26
  149. package/dist/singleton.js.map +1 -1
  150. package/dist/walkPrototypeChain.cjs +20 -12
  151. package/dist/walkPrototypeChain.cjs.map +1 -1
  152. package/dist/walkPrototypeChain.js +21 -13
  153. package/dist/walkPrototypeChain.js.map +1 -1
  154. package/dist/web/IndexedDBCollection.cjs +53 -36
  155. package/dist/web/IndexedDBCollection.cjs.map +1 -1
  156. package/dist/web/IndexedDBCollection.js +52 -35
  157. package/dist/web/IndexedDBCollection.js.map +1 -1
  158. package/dist/web/WebStorageCollection.cjs +82 -84
  159. package/dist/web/WebStorageCollection.cjs.map +1 -1
  160. package/dist/web/WebStorageCollection.js +81 -83
  161. package/dist/web/WebStorageCollection.js.map +1 -1
  162. package/dist/web/idb.cjs +107 -99
  163. package/dist/web/idb.cjs.map +1 -1
  164. package/dist/web/idb.js +108 -105
  165. package/dist/web/idb.js.map +1 -1
  166. package/dist/web.cjs +4 -6
  167. package/dist/web.js +1 -5
  168. package/dist/wrapAsyncMethods.cjs +141 -168
  169. package/dist/wrapAsyncMethods.cjs.map +1 -1
  170. package/dist/wrapAsyncMethods.js +141 -168
  171. package/dist/wrapAsyncMethods.js.map +1 -1
  172. package/package.json +8 -8
  173. package/src/Pending.test.ts +1 -2
  174. package/src/Sorting.test.ts +1 -1
  175. package/src/produceDraft.test.ts +3 -3
  176. package/src/react/components/CardList.test.tsx +1 -1
  177. package/src/react/components/DataTable.test.tsx +1 -1
  178. package/src/react/components/InfiniteScroll.test.tsx +5 -5
  179. package/dist/mvc-kit.cjs.map +0 -1
  180. package/dist/mvc-kit.js.map +0 -1
  181. package/dist/react-native.cjs.map +0 -1
  182. package/dist/react-native.js.map +0 -1
  183. package/dist/react.cjs.map +0 -1
  184. package/dist/react.js.map +0 -1
  185. package/dist/web.cjs.map +0 -1
  186. package/dist/web.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"InfiniteScroll.js","sources":["../../../src/react/components/InfiniteScroll.tsx"],"sourcesContent":["import { useRef, useEffect, type ReactNode } from 'react';\n\n/** Props for the InfiniteScroll headless component. */\nexport interface InfiniteScrollProps {\n hasMore: boolean;\n loading?: boolean;\n onLoadMore: () => void;\n threshold?: number;\n rootMargin?: string;\n direction?: 'down' | 'up';\n children: ReactNode;\n renderLoading?: () => ReactNode;\n renderEnd?: () => ReactNode;\n className?: string;\n}\n\n/**\n * Headless infinite scroll wrapper using IntersectionObserver.\n * Renders a sentinel element that triggers `onLoadMore` when visible.\n * Use `direction=\"up\"` for reverse-scroll chat UIs.\n */\nexport function InfiniteScroll({\n hasMore,\n loading = false,\n onLoadMore,\n threshold = 0.1,\n rootMargin = '0px',\n direction = 'down',\n children,\n renderLoading,\n renderEnd,\n className,\n}: InfiniteScrollProps) {\n const sentinelRef = useRef<HTMLDivElement>(null);\n const onLoadMoreRef = useRef(onLoadMore);\n onLoadMoreRef.current = onLoadMore;\n\n useEffect(() => {\n if (typeof IntersectionObserver === 'undefined') return;\n const sentinel = sentinelRef.current;\n if (!sentinel) return;\n\n const observer = new IntersectionObserver(\n (entries) => {\n if (entries[0]?.isIntersecting) {\n onLoadMoreRef.current();\n }\n },\n { threshold, rootMargin },\n );\n\n observer.observe(sentinel);\n return () => observer.disconnect();\n }, [threshold, rootMargin, hasMore, loading]);\n\n const style = direction === 'up'\n ? { display: 'flex', flexDirection: 'column-reverse' as const }\n : undefined;\n\n return (\n <div data-component=\"infinite-scroll\" className={className} style={style}>\n {children}\n {hasMore && !loading && (\n <div ref={sentinelRef} aria-hidden=\"true\" data-sentinel />\n )}\n {loading && renderLoading?.()}\n {!hasMore && renderEnd?.()}\n </div>\n );\n}\n"],"names":[],"mappings":";;AAqBO,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA,UAAU;AAAA,EACV;AAAA,EACA,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,YAAY;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAwB;AACtB,QAAM,cAAc,OAAuB,IAAI;AAC/C,QAAM,gBAAgB,OAAO,UAAU;AACvC,gBAAc,UAAU;AAExB,YAAU,MAAM;AACd,QAAI,OAAO,yBAAyB,YAAa;AACjD,UAAM,WAAW,YAAY;AAC7B,QAAI,CAAC,SAAU;AAEf,UAAM,WAAW,IAAI;AAAA,MACnB,CAAC,YAAY;AACX,YAAI,QAAQ,CAAC,GAAG,gBAAgB;AAC9B,wBAAc,QAAA;AAAA,QAChB;AAAA,MACF;AAAA,MACA,EAAE,WAAW,WAAA;AAAA,IAAW;AAG1B,aAAS,QAAQ,QAAQ;AACzB,WAAO,MAAM,SAAS,WAAA;AAAA,EACxB,GAAG,CAAC,WAAW,YAAY,SAAS,OAAO,CAAC;AAE5C,QAAM,QAAQ,cAAc,OACxB,EAAE,SAAS,QAAQ,eAAe,qBAClC;AAEJ,SACE,qBAAC,OAAA,EAAI,kBAAe,mBAAkB,WAAsB,OACzD,UAAA;AAAA,IAAA;AAAA,IACA,WAAW,CAAC,WACX,oBAAC,OAAA,EAAI,KAAK,aAAa,eAAY,QAAO,iBAAa,KAAA,CAAC;AAAA,IAEzD,WAAW,gBAAA;AAAA,IACX,CAAC,WAAW,YAAA;AAAA,EAAY,GAC3B;AAEJ;"}
1
+ {"version":3,"file":"InfiniteScroll.js","names":[],"sources":["../../../src/react/components/InfiniteScroll.tsx"],"sourcesContent":["import { useRef, useEffect, type ReactNode } from 'react';\n\n/** Props for the InfiniteScroll headless component. */\nexport interface InfiniteScrollProps {\n hasMore: boolean;\n loading?: boolean;\n onLoadMore: () => void;\n threshold?: number;\n rootMargin?: string;\n direction?: 'down' | 'up';\n children: ReactNode;\n renderLoading?: () => ReactNode;\n renderEnd?: () => ReactNode;\n className?: string;\n}\n\n/**\n * Headless infinite scroll wrapper using IntersectionObserver.\n * Renders a sentinel element that triggers `onLoadMore` when visible.\n * Use `direction=\"up\"` for reverse-scroll chat UIs.\n */\nexport function InfiniteScroll({\n hasMore,\n loading = false,\n onLoadMore,\n threshold = 0.1,\n rootMargin = '0px',\n direction = 'down',\n children,\n renderLoading,\n renderEnd,\n className,\n}: InfiniteScrollProps) {\n const sentinelRef = useRef<HTMLDivElement>(null);\n const onLoadMoreRef = useRef(onLoadMore);\n onLoadMoreRef.current = onLoadMore;\n\n useEffect(() => {\n if (typeof IntersectionObserver === 'undefined') return;\n const sentinel = sentinelRef.current;\n if (!sentinel) return;\n\n const observer = new IntersectionObserver(\n (entries) => {\n if (entries[0]?.isIntersecting) {\n onLoadMoreRef.current();\n }\n },\n { threshold, rootMargin },\n );\n\n observer.observe(sentinel);\n return () => observer.disconnect();\n }, [threshold, rootMargin, hasMore, loading]);\n\n const style = direction === 'up'\n ? { display: 'flex', flexDirection: 'column-reverse' as const }\n : undefined;\n\n return (\n <div data-component=\"infinite-scroll\" className={className} style={style}>\n {children}\n {hasMore && !loading && (\n <div ref={sentinelRef} aria-hidden=\"true\" data-sentinel />\n )}\n {loading && renderLoading?.()}\n {!hasMore && renderEnd?.()}\n </div>\n );\n}\n"],"mappings":";;;;;;;;AAqBA,SAAgB,eAAe,EAC7B,SACA,UAAU,OACV,YACA,YAAY,IACZ,aAAa,OACb,YAAY,QACZ,UACA,eACA,WACA,aACsB;CACtB,MAAM,cAAc,OAAuB,KAAK;CAChD,MAAM,gBAAgB,OAAO,WAAW;AACxC,eAAc,UAAU;AAExB,iBAAgB;AACd,MAAI,OAAO,yBAAyB,YAAa;EACjD,MAAM,WAAW,YAAY;AAC7B,MAAI,CAAC,SAAU;EAEf,MAAM,WAAW,IAAI,sBAClB,YAAY;AACX,OAAI,QAAQ,IAAI,eACd,eAAc,SAAS;KAG3B;GAAE;GAAW;GAAY,CAC1B;AAED,WAAS,QAAQ,SAAS;AAC1B,eAAa,SAAS,YAAY;IACjC;EAAC;EAAW;EAAY;EAAS;EAAQ,CAAC;AAM7C,QACE,qBAAC,OAAD;EAAK,kBAAe;EAA6B;EAAkB,OALvD,cAAc,OACxB;GAAE,SAAS;GAAQ,eAAe;GAA2B,GAC7D,KAAA;YAGF;GACG;GACA,WAAW,CAAC,WACX,oBAAC,OAAD;IAAK,KAAK;IAAa,eAAY;IAAO,iBAAA;IAAgB,CAAA;GAE3D,WAAW,iBAAiB;GAC5B,CAAC,WAAW,aAAa;GACtB"}
@@ -1,15 +1,19 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
1
+ //#region src/react/components/types.ts
2
+ /** @internal Detect whether a selection prop is a Selection helper instance. */
3
3
  function isSelectionHelper(s) {
4
- return "toggle" in s && !("onToggle" in s);
4
+ return "toggle" in s && !("onToggle" in s);
5
5
  }
6
+ /** @internal Detect whether a pagination prop is a Pagination helper instance. */
6
7
  function isPaginationHelper(p) {
7
- return "setPage" in p && !("onPageChange" in p);
8
+ return "setPage" in p && !("onPageChange" in p);
8
9
  }
10
+ /** @internal Detect whether a sort prop is a Sorting helper instance. */
9
11
  function isSortingHelper(s) {
10
- return s != null && !Array.isArray(s) && "sorts" in s && "toggle" in s;
12
+ return s != null && !Array.isArray(s) && "sorts" in s && "toggle" in s;
11
13
  }
14
+ //#endregion
12
15
  exports.isPaginationHelper = isPaginationHelper;
13
16
  exports.isSelectionHelper = isSelectionHelper;
14
17
  exports.isSortingHelper = isSortingHelper;
15
- //# sourceMappingURL=types.cjs.map
18
+
19
+ //# sourceMappingURL=types.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.cjs","sources":["../../../src/react/components/types.ts"],"sourcesContent":["import type { ReactNode } from 'react';\nimport type { SortDescriptor } from '../../Sorting';\n\n/** Props passed to a custom sort indicator render function. */\nexport interface SortHeaderProps {\n active: boolean;\n direction: 'asc' | 'desc';\n index: number;\n onToggle: () => void;\n}\n\n/** Controlled selection state using callback props. */\nexport interface SelectionState<K = string | number> {\n selected: ReadonlySet<K>;\n onToggle: (key: K) => void;\n onToggleAll: (allKeys: K[]) => void;\n}\n\n/** Structural interface matching Selection<K> — duck-type for direct helper pass-through. */\nexport interface SelectionHelper {\n readonly selected: ReadonlySet<any>;\n toggle(key: any): void;\n toggleAll(allKeys: any[]): void;\n}\n\n/** Controlled pagination state using callback props. */\nexport interface PaginationState {\n page: number;\n total: number;\n onPageChange: (page: number) => void;\n}\n\n/** Structural interface matching Pagination — duck-type for direct helper pass-through. */\nexport interface PaginationHelper {\n readonly page: number;\n readonly pageSize: number;\n setPage(page: number): void;\n}\n\n/** Structural interface matching Sorting<T> — duck-type for direct helper pass-through. */\nexport interface SortingHelper {\n readonly sorts: readonly SortDescriptor[];\n toggle(key: string): void;\n}\n\n/** Computed pagination info passed to renderPagination slots. */\nexport interface PaginationInfo {\n page: number;\n pageCount: number;\n total: number;\n pageSize: number;\n hasPrev: boolean;\n hasNext: boolean;\n goToPage: (p: number) => void;\n goPrev: () => void;\n goNext: () => void;\n}\n\n/** Loading and error state props for async-aware components. */\nexport interface AsyncStateProps {\n loading?: boolean;\n error?: string | null;\n}\n\n/** Column definition for DataTable. */\nexport interface Column<T> {\n key: string;\n header: ReactNode;\n render: (item: T, index: number) => ReactNode;\n sortable?: boolean;\n width?: string;\n align?: 'left' | 'center' | 'right';\n}\n\n// ── Detection functions (duck-type discriminators) ──\n\n/** @internal Detect whether a selection prop is a Selection helper instance. */\nexport function isSelectionHelper(s: SelectionState | SelectionHelper): s is SelectionHelper {\n return 'toggle' in s && !('onToggle' in s);\n}\n\n/** @internal Detect whether a pagination prop is a Pagination helper instance. */\nexport function isPaginationHelper(p: PaginationState | PaginationHelper): p is PaginationHelper {\n return 'setPage' in p && !('onPageChange' in p);\n}\n\n/** @internal Detect whether a sort prop is a Sorting helper instance. */\nexport function isSortingHelper(s: readonly SortDescriptor[] | SortingHelper): s is SortingHelper {\n return s != null && !Array.isArray(s) && 'sorts' in s && 'toggle' in s;\n}\n"],"names":[],"mappings":";;AA6EO,SAAS,kBAAkB,GAA2D;AAC3F,SAAO,YAAY,KAAK,EAAE,cAAc;AAC1C;AAGO,SAAS,mBAAmB,GAA8D;AAC/F,SAAO,aAAa,KAAK,EAAE,kBAAkB;AAC/C;AAGO,SAAS,gBAAgB,GAAkE;AAChG,SAAO,KAAK,QAAQ,CAAC,MAAM,QAAQ,CAAC,KAAK,WAAW,KAAK,YAAY;AACvE;;;;"}
1
+ {"version":3,"file":"types.cjs","names":[],"sources":["../../../src/react/components/types.ts"],"sourcesContent":["import type { ReactNode } from 'react';\nimport type { SortDescriptor } from '../../Sorting';\n\n/** Props passed to a custom sort indicator render function. */\nexport interface SortHeaderProps {\n active: boolean;\n direction: 'asc' | 'desc';\n index: number;\n onToggle: () => void;\n}\n\n/** Controlled selection state using callback props. */\nexport interface SelectionState<K = string | number> {\n selected: ReadonlySet<K>;\n onToggle: (key: K) => void;\n onToggleAll: (allKeys: K[]) => void;\n}\n\n/** Structural interface matching Selection<K> — duck-type for direct helper pass-through. */\nexport interface SelectionHelper {\n readonly selected: ReadonlySet<any>;\n toggle(key: any): void;\n toggleAll(allKeys: any[]): void;\n}\n\n/** Controlled pagination state using callback props. */\nexport interface PaginationState {\n page: number;\n total: number;\n onPageChange: (page: number) => void;\n}\n\n/** Structural interface matching Pagination — duck-type for direct helper pass-through. */\nexport interface PaginationHelper {\n readonly page: number;\n readonly pageSize: number;\n setPage(page: number): void;\n}\n\n/** Structural interface matching Sorting<T> — duck-type for direct helper pass-through. */\nexport interface SortingHelper {\n readonly sorts: readonly SortDescriptor[];\n toggle(key: string): void;\n}\n\n/** Computed pagination info passed to renderPagination slots. */\nexport interface PaginationInfo {\n page: number;\n pageCount: number;\n total: number;\n pageSize: number;\n hasPrev: boolean;\n hasNext: boolean;\n goToPage: (p: number) => void;\n goPrev: () => void;\n goNext: () => void;\n}\n\n/** Loading and error state props for async-aware components. */\nexport interface AsyncStateProps {\n loading?: boolean;\n error?: string | null;\n}\n\n/** Column definition for DataTable. */\nexport interface Column<T> {\n key: string;\n header: ReactNode;\n render: (item: T, index: number) => ReactNode;\n sortable?: boolean;\n width?: string;\n align?: 'left' | 'center' | 'right';\n}\n\n// ── Detection functions (duck-type discriminators) ──\n\n/** @internal Detect whether a selection prop is a Selection helper instance. */\nexport function isSelectionHelper(s: SelectionState | SelectionHelper): s is SelectionHelper {\n return 'toggle' in s && !('onToggle' in s);\n}\n\n/** @internal Detect whether a pagination prop is a Pagination helper instance. */\nexport function isPaginationHelper(p: PaginationState | PaginationHelper): p is PaginationHelper {\n return 'setPage' in p && !('onPageChange' in p);\n}\n\n/** @internal Detect whether a sort prop is a Sorting helper instance. */\nexport function isSortingHelper(s: readonly SortDescriptor[] | SortingHelper): s is SortingHelper {\n return s != null && !Array.isArray(s) && 'sorts' in s && 'toggle' in s;\n}\n"],"mappings":";;AA6EA,SAAgB,kBAAkB,GAA2D;AAC3F,QAAO,YAAY,KAAK,EAAE,cAAc;;;AAI1C,SAAgB,mBAAmB,GAA8D;AAC/F,QAAO,aAAa,KAAK,EAAE,kBAAkB;;;AAI/C,SAAgB,gBAAgB,GAAkE;AAChG,QAAO,KAAK,QAAQ,CAAC,MAAM,QAAQ,EAAE,IAAI,WAAW,KAAK,YAAY"}
@@ -1,15 +1,17 @@
1
+ //#region src/react/components/types.ts
2
+ /** @internal Detect whether a selection prop is a Selection helper instance. */
1
3
  function isSelectionHelper(s) {
2
- return "toggle" in s && !("onToggle" in s);
4
+ return "toggle" in s && !("onToggle" in s);
3
5
  }
6
+ /** @internal Detect whether a pagination prop is a Pagination helper instance. */
4
7
  function isPaginationHelper(p) {
5
- return "setPage" in p && !("onPageChange" in p);
8
+ return "setPage" in p && !("onPageChange" in p);
6
9
  }
10
+ /** @internal Detect whether a sort prop is a Sorting helper instance. */
7
11
  function isSortingHelper(s) {
8
- return s != null && !Array.isArray(s) && "sorts" in s && "toggle" in s;
12
+ return s != null && !Array.isArray(s) && "sorts" in s && "toggle" in s;
9
13
  }
10
- export {
11
- isPaginationHelper,
12
- isSelectionHelper,
13
- isSortingHelper
14
- };
15
- //# sourceMappingURL=types.js.map
14
+ //#endregion
15
+ export { isPaginationHelper, isSelectionHelper, isSortingHelper };
16
+
17
+ //# sourceMappingURL=types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sources":["../../../src/react/components/types.ts"],"sourcesContent":["import type { ReactNode } from 'react';\nimport type { SortDescriptor } from '../../Sorting';\n\n/** Props passed to a custom sort indicator render function. */\nexport interface SortHeaderProps {\n active: boolean;\n direction: 'asc' | 'desc';\n index: number;\n onToggle: () => void;\n}\n\n/** Controlled selection state using callback props. */\nexport interface SelectionState<K = string | number> {\n selected: ReadonlySet<K>;\n onToggle: (key: K) => void;\n onToggleAll: (allKeys: K[]) => void;\n}\n\n/** Structural interface matching Selection<K> — duck-type for direct helper pass-through. */\nexport interface SelectionHelper {\n readonly selected: ReadonlySet<any>;\n toggle(key: any): void;\n toggleAll(allKeys: any[]): void;\n}\n\n/** Controlled pagination state using callback props. */\nexport interface PaginationState {\n page: number;\n total: number;\n onPageChange: (page: number) => void;\n}\n\n/** Structural interface matching Pagination — duck-type for direct helper pass-through. */\nexport interface PaginationHelper {\n readonly page: number;\n readonly pageSize: number;\n setPage(page: number): void;\n}\n\n/** Structural interface matching Sorting<T> — duck-type for direct helper pass-through. */\nexport interface SortingHelper {\n readonly sorts: readonly SortDescriptor[];\n toggle(key: string): void;\n}\n\n/** Computed pagination info passed to renderPagination slots. */\nexport interface PaginationInfo {\n page: number;\n pageCount: number;\n total: number;\n pageSize: number;\n hasPrev: boolean;\n hasNext: boolean;\n goToPage: (p: number) => void;\n goPrev: () => void;\n goNext: () => void;\n}\n\n/** Loading and error state props for async-aware components. */\nexport interface AsyncStateProps {\n loading?: boolean;\n error?: string | null;\n}\n\n/** Column definition for DataTable. */\nexport interface Column<T> {\n key: string;\n header: ReactNode;\n render: (item: T, index: number) => ReactNode;\n sortable?: boolean;\n width?: string;\n align?: 'left' | 'center' | 'right';\n}\n\n// ── Detection functions (duck-type discriminators) ──\n\n/** @internal Detect whether a selection prop is a Selection helper instance. */\nexport function isSelectionHelper(s: SelectionState | SelectionHelper): s is SelectionHelper {\n return 'toggle' in s && !('onToggle' in s);\n}\n\n/** @internal Detect whether a pagination prop is a Pagination helper instance. */\nexport function isPaginationHelper(p: PaginationState | PaginationHelper): p is PaginationHelper {\n return 'setPage' in p && !('onPageChange' in p);\n}\n\n/** @internal Detect whether a sort prop is a Sorting helper instance. */\nexport function isSortingHelper(s: readonly SortDescriptor[] | SortingHelper): s is SortingHelper {\n return s != null && !Array.isArray(s) && 'sorts' in s && 'toggle' in s;\n}\n"],"names":[],"mappings":"AA6EO,SAAS,kBAAkB,GAA2D;AAC3F,SAAO,YAAY,KAAK,EAAE,cAAc;AAC1C;AAGO,SAAS,mBAAmB,GAA8D;AAC/F,SAAO,aAAa,KAAK,EAAE,kBAAkB;AAC/C;AAGO,SAAS,gBAAgB,GAAkE;AAChG,SAAO,KAAK,QAAQ,CAAC,MAAM,QAAQ,CAAC,KAAK,WAAW,KAAK,YAAY;AACvE;"}
1
+ {"version":3,"file":"types.js","names":[],"sources":["../../../src/react/components/types.ts"],"sourcesContent":["import type { ReactNode } from 'react';\nimport type { SortDescriptor } from '../../Sorting';\n\n/** Props passed to a custom sort indicator render function. */\nexport interface SortHeaderProps {\n active: boolean;\n direction: 'asc' | 'desc';\n index: number;\n onToggle: () => void;\n}\n\n/** Controlled selection state using callback props. */\nexport interface SelectionState<K = string | number> {\n selected: ReadonlySet<K>;\n onToggle: (key: K) => void;\n onToggleAll: (allKeys: K[]) => void;\n}\n\n/** Structural interface matching Selection<K> — duck-type for direct helper pass-through. */\nexport interface SelectionHelper {\n readonly selected: ReadonlySet<any>;\n toggle(key: any): void;\n toggleAll(allKeys: any[]): void;\n}\n\n/** Controlled pagination state using callback props. */\nexport interface PaginationState {\n page: number;\n total: number;\n onPageChange: (page: number) => void;\n}\n\n/** Structural interface matching Pagination — duck-type for direct helper pass-through. */\nexport interface PaginationHelper {\n readonly page: number;\n readonly pageSize: number;\n setPage(page: number): void;\n}\n\n/** Structural interface matching Sorting<T> — duck-type for direct helper pass-through. */\nexport interface SortingHelper {\n readonly sorts: readonly SortDescriptor[];\n toggle(key: string): void;\n}\n\n/** Computed pagination info passed to renderPagination slots. */\nexport interface PaginationInfo {\n page: number;\n pageCount: number;\n total: number;\n pageSize: number;\n hasPrev: boolean;\n hasNext: boolean;\n goToPage: (p: number) => void;\n goPrev: () => void;\n goNext: () => void;\n}\n\n/** Loading and error state props for async-aware components. */\nexport interface AsyncStateProps {\n loading?: boolean;\n error?: string | null;\n}\n\n/** Column definition for DataTable. */\nexport interface Column<T> {\n key: string;\n header: ReactNode;\n render: (item: T, index: number) => ReactNode;\n sortable?: boolean;\n width?: string;\n align?: 'left' | 'center' | 'right';\n}\n\n// ── Detection functions (duck-type discriminators) ──\n\n/** @internal Detect whether a selection prop is a Selection helper instance. */\nexport function isSelectionHelper(s: SelectionState | SelectionHelper): s is SelectionHelper {\n return 'toggle' in s && !('onToggle' in s);\n}\n\n/** @internal Detect whether a pagination prop is a Pagination helper instance. */\nexport function isPaginationHelper(p: PaginationState | PaginationHelper): p is PaginationHelper {\n return 'setPage' in p && !('onPageChange' in p);\n}\n\n/** @internal Detect whether a sort prop is a Sorting helper instance. */\nexport function isSortingHelper(s: readonly SortDescriptor[] | SortingHelper): s is SortingHelper {\n return s != null && !Array.isArray(s) && 'sorts' in s && 'toggle' in s;\n}\n"],"mappings":";;AA6EA,SAAgB,kBAAkB,GAA2D;AAC3F,QAAO,YAAY,KAAK,EAAE,cAAc;;;AAI1C,SAAgB,mBAAmB,GAA8D;AAC/F,QAAO,aAAa,KAAK,EAAE,kBAAkB;;;AAI/C,SAAgB,gBAAgB,GAAkE;AAChG,QAAO,KAAK,QAAQ,CAAC,MAAM,QAAQ,EAAE,IAAI,WAAW,KAAK,YAAY"}
@@ -1,9 +1,13 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const isSubscribable = (obj) => obj !== null && typeof obj === "object" && "state" in obj && "subscribe" in obj && typeof obj.subscribe === "function";
4
- const isInitializable = (obj) => obj !== null && typeof obj === "object" && "init" in obj && typeof obj.init === "function";
5
- const isSubscribeOnly = (obj) => obj !== null && typeof obj === "object" && !("state" in obj) && "subscribe" in obj && typeof obj.subscribe === "function";
1
+ //#region src/react/guards.ts
2
+ /** @internal Type guard for Subscribable */
3
+ var isSubscribable = (obj) => obj !== null && typeof obj === "object" && "state" in obj && "subscribe" in obj && typeof obj.subscribe === "function";
4
+ /** @internal Type guard for Initializable */
5
+ var isInitializable = (obj) => obj !== null && typeof obj === "object" && "init" in obj && typeof obj.init === "function";
6
+ /** @internal Type guard for subscribe-only objects (has subscribe but no state). */
7
+ var isSubscribeOnly = (obj) => obj !== null && typeof obj === "object" && !("state" in obj) && "subscribe" in obj && typeof obj.subscribe === "function";
8
+ //#endregion
6
9
  exports.isInitializable = isInitializable;
7
10
  exports.isSubscribable = isSubscribable;
8
11
  exports.isSubscribeOnly = isSubscribeOnly;
9
- //# sourceMappingURL=guards.cjs.map
12
+
13
+ //# sourceMappingURL=guards.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"guards.cjs","sources":["../../src/react/guards.ts"],"sourcesContent":["import type { Subscribable } from '../types';\n\n/** @internal Type guard for Subscribable */\nexport const isSubscribable = (obj: unknown): obj is Subscribable<unknown> =>\n obj !== null &&\n typeof obj === 'object' &&\n 'state' in obj &&\n 'subscribe' in obj &&\n typeof (obj as Subscribable<unknown>).subscribe === 'function';\n\n/** @internal Type guard for Initializable */\nexport const isInitializable = (obj: unknown): obj is { init(): void | Promise<void> } =>\n obj !== null &&\n typeof obj === 'object' &&\n 'init' in obj &&\n typeof (obj as any).init === 'function';\n\n/** @internal Type guard for subscribe-only objects (has subscribe but no state). */\nexport const isSubscribeOnly = (obj: unknown): obj is { subscribe(cb: () => void): () => void } =>\n obj !== null &&\n typeof obj === 'object' &&\n !('state' in obj) &&\n 'subscribe' in obj &&\n typeof (obj as any).subscribe === 'function';\n"],"names":[],"mappings":";;AAGO,MAAM,iBAAiB,CAAC,QAC7B,QAAQ,QACR,OAAO,QAAQ,YACf,WAAW,OACX,eAAe,OACf,OAAQ,IAA8B,cAAc;AAG/C,MAAM,kBAAkB,CAAC,QAC9B,QAAQ,QACR,OAAO,QAAQ,YACf,UAAU,OACV,OAAQ,IAAY,SAAS;AAGxB,MAAM,kBAAkB,CAAC,QAC9B,QAAQ,QACR,OAAO,QAAQ,YACf,EAAE,WAAW,QACb,eAAe,OACf,OAAQ,IAAY,cAAc;;;;"}
1
+ {"version":3,"file":"guards.cjs","names":[],"sources":["../../src/react/guards.ts"],"sourcesContent":["import type { Subscribable } from '../types';\n\n/** @internal Type guard for Subscribable */\nexport const isSubscribable = (obj: unknown): obj is Subscribable<unknown> =>\n obj !== null &&\n typeof obj === 'object' &&\n 'state' in obj &&\n 'subscribe' in obj &&\n typeof (obj as Subscribable<unknown>).subscribe === 'function';\n\n/** @internal Type guard for Initializable */\nexport const isInitializable = (obj: unknown): obj is { init(): void | Promise<void> } =>\n obj !== null &&\n typeof obj === 'object' &&\n 'init' in obj &&\n typeof (obj as any).init === 'function';\n\n/** @internal Type guard for subscribe-only objects (has subscribe but no state). */\nexport const isSubscribeOnly = (obj: unknown): obj is { subscribe(cb: () => void): () => void } =>\n obj !== null &&\n typeof obj === 'object' &&\n !('state' in obj) &&\n 'subscribe' in obj &&\n typeof (obj as any).subscribe === 'function';\n"],"mappings":";;AAGA,IAAa,kBAAkB,QAC7B,QAAQ,QACR,OAAO,QAAQ,YACf,WAAW,OACX,eAAe,OACf,OAAQ,IAA8B,cAAc;;AAGtD,IAAa,mBAAmB,QAC9B,QAAQ,QACR,OAAO,QAAQ,YACf,UAAU,OACV,OAAQ,IAAY,SAAS;;AAG/B,IAAa,mBAAmB,QAC9B,QAAQ,QACR,OAAO,QAAQ,YACf,EAAE,WAAW,QACb,eAAe,OACf,OAAQ,IAAY,cAAc"}
@@ -1,9 +1,11 @@
1
- const isSubscribable = (obj) => obj !== null && typeof obj === "object" && "state" in obj && "subscribe" in obj && typeof obj.subscribe === "function";
2
- const isInitializable = (obj) => obj !== null && typeof obj === "object" && "init" in obj && typeof obj.init === "function";
3
- const isSubscribeOnly = (obj) => obj !== null && typeof obj === "object" && !("state" in obj) && "subscribe" in obj && typeof obj.subscribe === "function";
4
- export {
5
- isInitializable,
6
- isSubscribable,
7
- isSubscribeOnly
8
- };
9
- //# sourceMappingURL=guards.js.map
1
+ //#region src/react/guards.ts
2
+ /** @internal Type guard for Subscribable */
3
+ var isSubscribable = (obj) => obj !== null && typeof obj === "object" && "state" in obj && "subscribe" in obj && typeof obj.subscribe === "function";
4
+ /** @internal Type guard for Initializable */
5
+ var isInitializable = (obj) => obj !== null && typeof obj === "object" && "init" in obj && typeof obj.init === "function";
6
+ /** @internal Type guard for subscribe-only objects (has subscribe but no state). */
7
+ var isSubscribeOnly = (obj) => obj !== null && typeof obj === "object" && !("state" in obj) && "subscribe" in obj && typeof obj.subscribe === "function";
8
+ //#endregion
9
+ export { isInitializable, isSubscribable, isSubscribeOnly };
10
+
11
+ //# sourceMappingURL=guards.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"guards.js","sources":["../../src/react/guards.ts"],"sourcesContent":["import type { Subscribable } from '../types';\n\n/** @internal Type guard for Subscribable */\nexport const isSubscribable = (obj: unknown): obj is Subscribable<unknown> =>\n obj !== null &&\n typeof obj === 'object' &&\n 'state' in obj &&\n 'subscribe' in obj &&\n typeof (obj as Subscribable<unknown>).subscribe === 'function';\n\n/** @internal Type guard for Initializable */\nexport const isInitializable = (obj: unknown): obj is { init(): void | Promise<void> } =>\n obj !== null &&\n typeof obj === 'object' &&\n 'init' in obj &&\n typeof (obj as any).init === 'function';\n\n/** @internal Type guard for subscribe-only objects (has subscribe but no state). */\nexport const isSubscribeOnly = (obj: unknown): obj is { subscribe(cb: () => void): () => void } =>\n obj !== null &&\n typeof obj === 'object' &&\n !('state' in obj) &&\n 'subscribe' in obj &&\n typeof (obj as any).subscribe === 'function';\n"],"names":[],"mappings":"AAGO,MAAM,iBAAiB,CAAC,QAC7B,QAAQ,QACR,OAAO,QAAQ,YACf,WAAW,OACX,eAAe,OACf,OAAQ,IAA8B,cAAc;AAG/C,MAAM,kBAAkB,CAAC,QAC9B,QAAQ,QACR,OAAO,QAAQ,YACf,UAAU,OACV,OAAQ,IAAY,SAAS;AAGxB,MAAM,kBAAkB,CAAC,QAC9B,QAAQ,QACR,OAAO,QAAQ,YACf,EAAE,WAAW,QACb,eAAe,OACf,OAAQ,IAAY,cAAc;"}
1
+ {"version":3,"file":"guards.js","names":[],"sources":["../../src/react/guards.ts"],"sourcesContent":["import type { Subscribable } from '../types';\n\n/** @internal Type guard for Subscribable */\nexport const isSubscribable = (obj: unknown): obj is Subscribable<unknown> =>\n obj !== null &&\n typeof obj === 'object' &&\n 'state' in obj &&\n 'subscribe' in obj &&\n typeof (obj as Subscribable<unknown>).subscribe === 'function';\n\n/** @internal Type guard for Initializable */\nexport const isInitializable = (obj: unknown): obj is { init(): void | Promise<void> } =>\n obj !== null &&\n typeof obj === 'object' &&\n 'init' in obj &&\n typeof (obj as any).init === 'function';\n\n/** @internal Type guard for subscribe-only objects (has subscribe but no state). */\nexport const isSubscribeOnly = (obj: unknown): obj is { subscribe(cb: () => void): () => void } =>\n obj !== null &&\n typeof obj === 'object' &&\n !('state' in obj) &&\n 'subscribe' in obj &&\n typeof (obj as any).subscribe === 'function';\n"],"mappings":";;AAGA,IAAa,kBAAkB,QAC7B,QAAQ,QACR,OAAO,QAAQ,YACf,WAAW,OACX,eAAe,OACf,OAAQ,IAA8B,cAAc;;AAGtD,IAAa,mBAAmB,QAC9B,QAAQ,QACR,OAAO,QAAQ,YACf,UAAU,OACV,OAAQ,IAAY,SAAS;;AAG/B,IAAa,mBAAmB,QAC9B,QAAQ,QACR,OAAO,QAAQ,YACf,EAAE,WAAW,QACb,eAAe,OACf,OAAQ,IAAY,cAAc"}
@@ -1,26 +1,29 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const jsxRuntime = require("react/jsx-runtime");
4
- const react = require("react");
5
- const singleton = require("../singleton.cjs");
6
- const ProviderContext = react.createContext(null);
1
+ const require_singleton = require("../singleton.cjs");
2
+ let react = require("react");
3
+ let react_jsx_runtime = require("react/jsx-runtime");
4
+ //#region src/react/provider.tsx
5
+ var ProviderContext = (0, react.createContext)(null);
6
+ /**
7
+ * DI container for testing and Storybook.
8
+ */
7
9
  function Provider({ provide, children }) {
8
- const registry = react.useMemo(() => {
9
- const map = /* @__PURE__ */ new Map();
10
- for (const [Class, instance] of provide) {
11
- map.set(Class, instance);
12
- }
13
- return map;
14
- }, [provide]);
15
- return /* @__PURE__ */ jsxRuntime.jsx(ProviderContext.Provider, { value: registry, children });
10
+ const registry = (0, react.useMemo)(() => {
11
+ const map = /* @__PURE__ */ new Map();
12
+ for (const [Class, instance] of provide) map.set(Class, instance);
13
+ return map;
14
+ }, [provide]);
15
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProviderContext.Provider, {
16
+ value: registry,
17
+ children
18
+ });
16
19
  }
17
20
  function useResolve(Class, ...args) {
18
- const registry = react.useContext(ProviderContext);
19
- if (registry?.has(Class)) {
20
- return registry.get(Class);
21
- }
22
- return singleton.singleton(Class, ...args);
21
+ const registry = (0, react.useContext)(ProviderContext);
22
+ if (registry?.has(Class)) return registry.get(Class);
23
+ return require_singleton.singleton(Class, ...args);
23
24
  }
25
+ //#endregion
24
26
  exports.Provider = Provider;
25
27
  exports.useResolve = useResolve;
26
- //# sourceMappingURL=provider.cjs.map
28
+
29
+ //# sourceMappingURL=provider.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"provider.cjs","sources":["../../src/react/provider.tsx"],"sourcesContent":["import { createContext, useContext, useMemo, type ReactNode } from 'react';\nimport { singleton } from '../singleton';\nimport type { Disposable } from '../types';\nimport type { ProviderRegistry } from './types';\n\nconst ProviderContext = createContext<ProviderRegistry | null>(null);\n\n/** Props for the `Provider` component used to inject test/Storybook dependencies. */\nexport interface ProviderProps {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n provide: Array<[new (...args: any[]) => any, any]>;\n children: ReactNode;\n}\n\n/**\n * DI container for testing and Storybook.\n */\nexport function Provider({ provide, children }: ProviderProps): ReactNode {\n const registry = useMemo(() => {\n const map: ProviderRegistry = new Map();\n for (const [Class, instance] of provide) {\n map.set(Class, instance);\n }\n return map;\n }, [provide]);\n\n return (\n <ProviderContext.Provider value={registry}>\n {children}\n </ProviderContext.Provider>\n );\n}\n\n/**\n * Resolve from Provider context or fallback to singleton().\n * If the class defines `static DEFAULT_STATE`, no constructor args are needed.\n */\nexport function useResolve<T>(\n Class: (new (...args: any[]) => T) & { DEFAULT_STATE: unknown },\n): T;\nexport function useResolve<T, Args extends unknown[] = unknown[]>(\n Class: new (...args: Args) => T,\n ...args: Args\n): T;\nexport function useResolve<T, Args extends unknown[] = unknown[]>(\n Class: (new (...args: Args) => T) & { DEFAULT_STATE?: unknown },\n ...args: Args\n): T {\n const registry = useContext(ProviderContext);\n\n if (registry?.has(Class)) {\n return registry.get(Class) as T;\n }\n return singleton(Class as new (...args: Args) => T & Disposable, ...args);\n}\n"],"names":["createContext","useMemo","useContext","singleton"],"mappings":";;;;;AAKA,MAAM,kBAAkBA,MAAAA,cAAuC,IAAI;AAY5D,SAAS,SAAS,EAAE,SAAS,YAAsC;AACxE,QAAM,WAAWC,MAAAA,QAAQ,MAAM;AAC7B,UAAM,0BAA4B,IAAA;AAClC,eAAW,CAAC,OAAO,QAAQ,KAAK,SAAS;AACvC,UAAI,IAAI,OAAO,QAAQ;AAAA,IACzB;AACA,WAAO;AAAA,EACT,GAAG,CAAC,OAAO,CAAC;AAEZ,wCACG,gBAAgB,UAAhB,EAAyB,OAAO,UAC9B,UACH;AAEJ;AAaO,SAAS,WACd,UACG,MACA;AACH,QAAM,WAAWC,MAAAA,WAAW,eAAe;AAE3C,MAAI,UAAU,IAAI,KAAK,GAAG;AACxB,WAAO,SAAS,IAAI,KAAK;AAAA,EAC3B;AACA,SAAOC,UAAAA,UAAU,OAAgD,GAAG,IAAI;AAC1E;;;"}
1
+ {"version":3,"file":"provider.cjs","names":[],"sources":["../../src/react/provider.tsx"],"sourcesContent":["import { createContext, useContext, useMemo, type ReactNode } from 'react';\nimport { singleton } from '../singleton';\nimport type { Disposable } from '../types';\nimport type { ProviderRegistry } from './types';\n\nconst ProviderContext = createContext<ProviderRegistry | null>(null);\n\n/** Props for the `Provider` component used to inject test/Storybook dependencies. */\nexport interface ProviderProps {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n provide: Array<[new (...args: any[]) => any, any]>;\n children: ReactNode;\n}\n\n/**\n * DI container for testing and Storybook.\n */\nexport function Provider({ provide, children }: ProviderProps): ReactNode {\n const registry = useMemo(() => {\n const map: ProviderRegistry = new Map();\n for (const [Class, instance] of provide) {\n map.set(Class, instance);\n }\n return map;\n }, [provide]);\n\n return (\n <ProviderContext.Provider value={registry}>\n {children}\n </ProviderContext.Provider>\n );\n}\n\n/**\n * Resolve from Provider context or fallback to singleton().\n * If the class defines `static DEFAULT_STATE`, no constructor args are needed.\n */\nexport function useResolve<T>(\n Class: (new (...args: any[]) => T) & { DEFAULT_STATE: unknown },\n): T;\nexport function useResolve<T, Args extends unknown[] = unknown[]>(\n Class: new (...args: Args) => T,\n ...args: Args\n): T;\nexport function useResolve<T, Args extends unknown[] = unknown[]>(\n Class: (new (...args: Args) => T) & { DEFAULT_STATE?: unknown },\n ...args: Args\n): T {\n const registry = useContext(ProviderContext);\n\n if (registry?.has(Class)) {\n return registry.get(Class) as T;\n }\n return singleton(Class as new (...args: Args) => T & Disposable, ...args);\n}\n"],"mappings":";;;;AAKA,IAAM,mBAAA,GAAA,MAAA,eAAyD,KAAK;;;;AAYpE,SAAgB,SAAS,EAAE,SAAS,YAAsC;CACxE,MAAM,YAAA,GAAA,MAAA,eAAyB;EAC7B,MAAM,sBAAwB,IAAI,KAAK;AACvC,OAAK,MAAM,CAAC,OAAO,aAAa,QAC9B,KAAI,IAAI,OAAO,SAAS;AAE1B,SAAO;IACN,CAAC,QAAQ,CAAC;AAEb,QACE,iBAAA,GAAA,kBAAA,KAAC,gBAAgB,UAAjB;EAA0B,OAAO;EAC9B;EACwB,CAAA;;AAe/B,SAAgB,WACd,OACA,GAAG,MACA;CACH,MAAM,YAAA,GAAA,MAAA,YAAsB,gBAAgB;AAE5C,KAAI,UAAU,IAAI,MAAM,CACtB,QAAO,SAAS,IAAI,MAAM;AAE5B,QAAO,kBAAA,UAAU,OAAgD,GAAG,KAAK"}
@@ -1,26 +1,28 @@
1
- import { jsx } from "react/jsx-runtime";
2
- import { useMemo, useContext, createContext } from "react";
3
1
  import { singleton } from "../singleton.js";
4
- const ProviderContext = createContext(null);
2
+ import { createContext, useContext, useMemo } from "react";
3
+ import { jsx } from "react/jsx-runtime";
4
+ //#region src/react/provider.tsx
5
+ var ProviderContext = createContext(null);
6
+ /**
7
+ * DI container for testing and Storybook.
8
+ */
5
9
  function Provider({ provide, children }) {
6
- const registry = useMemo(() => {
7
- const map = /* @__PURE__ */ new Map();
8
- for (const [Class, instance] of provide) {
9
- map.set(Class, instance);
10
- }
11
- return map;
12
- }, [provide]);
13
- return /* @__PURE__ */ jsx(ProviderContext.Provider, { value: registry, children });
10
+ const registry = useMemo(() => {
11
+ const map = /* @__PURE__ */ new Map();
12
+ for (const [Class, instance] of provide) map.set(Class, instance);
13
+ return map;
14
+ }, [provide]);
15
+ return /* @__PURE__ */ jsx(ProviderContext.Provider, {
16
+ value: registry,
17
+ children
18
+ });
14
19
  }
15
20
  function useResolve(Class, ...args) {
16
- const registry = useContext(ProviderContext);
17
- if (registry?.has(Class)) {
18
- return registry.get(Class);
19
- }
20
- return singleton(Class, ...args);
21
+ const registry = useContext(ProviderContext);
22
+ if (registry?.has(Class)) return registry.get(Class);
23
+ return singleton(Class, ...args);
21
24
  }
22
- export {
23
- Provider,
24
- useResolve
25
- };
26
- //# sourceMappingURL=provider.js.map
25
+ //#endregion
26
+ export { Provider, useResolve };
27
+
28
+ //# sourceMappingURL=provider.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"provider.js","sources":["../../src/react/provider.tsx"],"sourcesContent":["import { createContext, useContext, useMemo, type ReactNode } from 'react';\nimport { singleton } from '../singleton';\nimport type { Disposable } from '../types';\nimport type { ProviderRegistry } from './types';\n\nconst ProviderContext = createContext<ProviderRegistry | null>(null);\n\n/** Props for the `Provider` component used to inject test/Storybook dependencies. */\nexport interface ProviderProps {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n provide: Array<[new (...args: any[]) => any, any]>;\n children: ReactNode;\n}\n\n/**\n * DI container for testing and Storybook.\n */\nexport function Provider({ provide, children }: ProviderProps): ReactNode {\n const registry = useMemo(() => {\n const map: ProviderRegistry = new Map();\n for (const [Class, instance] of provide) {\n map.set(Class, instance);\n }\n return map;\n }, [provide]);\n\n return (\n <ProviderContext.Provider value={registry}>\n {children}\n </ProviderContext.Provider>\n );\n}\n\n/**\n * Resolve from Provider context or fallback to singleton().\n * If the class defines `static DEFAULT_STATE`, no constructor args are needed.\n */\nexport function useResolve<T>(\n Class: (new (...args: any[]) => T) & { DEFAULT_STATE: unknown },\n): T;\nexport function useResolve<T, Args extends unknown[] = unknown[]>(\n Class: new (...args: Args) => T,\n ...args: Args\n): T;\nexport function useResolve<T, Args extends unknown[] = unknown[]>(\n Class: (new (...args: Args) => T) & { DEFAULT_STATE?: unknown },\n ...args: Args\n): T {\n const registry = useContext(ProviderContext);\n\n if (registry?.has(Class)) {\n return registry.get(Class) as T;\n }\n return singleton(Class as new (...args: Args) => T & Disposable, ...args);\n}\n"],"names":[],"mappings":";;;AAKA,MAAM,kBAAkB,cAAuC,IAAI;AAY5D,SAAS,SAAS,EAAE,SAAS,YAAsC;AACxE,QAAM,WAAW,QAAQ,MAAM;AAC7B,UAAM,0BAA4B,IAAA;AAClC,eAAW,CAAC,OAAO,QAAQ,KAAK,SAAS;AACvC,UAAI,IAAI,OAAO,QAAQ;AAAA,IACzB;AACA,WAAO;AAAA,EACT,GAAG,CAAC,OAAO,CAAC;AAEZ,6BACG,gBAAgB,UAAhB,EAAyB,OAAO,UAC9B,UACH;AAEJ;AAaO,SAAS,WACd,UACG,MACA;AACH,QAAM,WAAW,WAAW,eAAe;AAE3C,MAAI,UAAU,IAAI,KAAK,GAAG;AACxB,WAAO,SAAS,IAAI,KAAK;AAAA,EAC3B;AACA,SAAO,UAAU,OAAgD,GAAG,IAAI;AAC1E;"}
1
+ {"version":3,"file":"provider.js","names":[],"sources":["../../src/react/provider.tsx"],"sourcesContent":["import { createContext, useContext, useMemo, type ReactNode } from 'react';\nimport { singleton } from '../singleton';\nimport type { Disposable } from '../types';\nimport type { ProviderRegistry } from './types';\n\nconst ProviderContext = createContext<ProviderRegistry | null>(null);\n\n/** Props for the `Provider` component used to inject test/Storybook dependencies. */\nexport interface ProviderProps {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n provide: Array<[new (...args: any[]) => any, any]>;\n children: ReactNode;\n}\n\n/**\n * DI container for testing and Storybook.\n */\nexport function Provider({ provide, children }: ProviderProps): ReactNode {\n const registry = useMemo(() => {\n const map: ProviderRegistry = new Map();\n for (const [Class, instance] of provide) {\n map.set(Class, instance);\n }\n return map;\n }, [provide]);\n\n return (\n <ProviderContext.Provider value={registry}>\n {children}\n </ProviderContext.Provider>\n );\n}\n\n/**\n * Resolve from Provider context or fallback to singleton().\n * If the class defines `static DEFAULT_STATE`, no constructor args are needed.\n */\nexport function useResolve<T>(\n Class: (new (...args: any[]) => T) & { DEFAULT_STATE: unknown },\n): T;\nexport function useResolve<T, Args extends unknown[] = unknown[]>(\n Class: new (...args: Args) => T,\n ...args: Args\n): T;\nexport function useResolve<T, Args extends unknown[] = unknown[]>(\n Class: (new (...args: Args) => T) & { DEFAULT_STATE?: unknown },\n ...args: Args\n): T {\n const registry = useContext(ProviderContext);\n\n if (registry?.has(Class)) {\n return registry.get(Class) as T;\n }\n return singleton(Class as new (...args: Args) => T & Disposable, ...args);\n}\n"],"mappings":";;;;AAKA,IAAM,kBAAkB,cAAuC,KAAK;;;;AAYpE,SAAgB,SAAS,EAAE,SAAS,YAAsC;CACxE,MAAM,WAAW,cAAc;EAC7B,MAAM,sBAAwB,IAAI,KAAK;AACvC,OAAK,MAAM,CAAC,OAAO,aAAa,QAC9B,KAAI,IAAI,OAAO,SAAS;AAE1B,SAAO;IACN,CAAC,QAAQ,CAAC;AAEb,QACE,oBAAC,gBAAgB,UAAjB;EAA0B,OAAO;EAC9B;EACwB,CAAA;;AAe/B,SAAgB,WACd,OACA,GAAG,MACA;CACH,MAAM,WAAW,WAAW,gBAAgB;AAE5C,KAAI,UAAU,IAAI,MAAM,CACtB,QAAO,SAAS,IAAI,MAAM;AAE5B,QAAO,UAAU,OAAgD,GAAG,KAAK"}
@@ -1,26 +1,30 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const react = require("react");
4
- const EventBus = require("../EventBus.cjs");
1
+ const require_EventBus = require("../EventBus.cjs");
2
+ let react = require("react");
3
+ //#region src/react/use-event-bus.ts
4
+ /**
5
+ * Subscribe to a typed event, auto-unsubscribes on unmount.
6
+ * Accepts an EventBus directly or any object with an `events` property (e.g. a ViewModel).
7
+ */
5
8
  function useEvent(source, event, handler) {
6
- const bus = source instanceof EventBus.EventBus ? source : source.events;
7
- const handlerRef = react.useRef(handler);
8
- handlerRef.current = handler;
9
- react.useEffect(() => {
10
- const unsubscribe = bus.on(event, (payload) => {
11
- handlerRef.current(payload);
12
- });
13
- return unsubscribe;
14
- }, [bus, event]);
9
+ const bus = source instanceof require_EventBus.EventBus ? source : source.events;
10
+ const handlerRef = (0, react.useRef)(handler);
11
+ handlerRef.current = handler;
12
+ (0, react.useEffect)(() => {
13
+ return bus.on(event, (payload) => {
14
+ handlerRef.current(payload);
15
+ });
16
+ }, [bus, event]);
15
17
  }
18
+ /**
19
+ * Get a stable emit function for an EventBus.
20
+ */
16
21
  function useEmit(bus) {
17
- return react.useCallback(
18
- (event, payload) => {
19
- bus.emit(event, payload);
20
- },
21
- [bus]
22
- );
22
+ return (0, react.useCallback)((event, payload) => {
23
+ bus.emit(event, payload);
24
+ }, [bus]);
23
25
  }
26
+ //#endregion
24
27
  exports.useEmit = useEmit;
25
28
  exports.useEvent = useEvent;
26
- //# sourceMappingURL=use-event-bus.cjs.map
29
+
30
+ //# sourceMappingURL=use-event-bus.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-event-bus.cjs","sources":["../../src/react/use-event-bus.ts"],"sourcesContent":["import { useEffect, useCallback, useRef } from 'react';\nimport { EventBus } from '../EventBus';\n\n/**\n * Subscribe to a typed event, auto-unsubscribes on unmount.\n * Accepts an EventBus directly or any object with an `events` property (e.g. a ViewModel).\n */\nexport function useEvent<E extends Record<string, any>, K extends keyof E>(\n source: EventBus<E> | { events: EventBus<E> },\n event: K,\n handler: (payload: E[K]) => void\n): void {\n const bus = source instanceof EventBus ? source : source.events;\n\n // Use ref to keep handler stable across re-renders\n const handlerRef = useRef(handler);\n handlerRef.current = handler;\n\n useEffect(() => {\n const unsubscribe = bus.on(event, (payload) => {\n handlerRef.current(payload);\n });\n\n return unsubscribe;\n }, [bus, event]);\n}\n\n/**\n * Get a stable emit function for an EventBus.\n */\nexport function useEmit<E extends Record<string, any>>(\n bus: EventBus<E>\n): <K extends keyof E>(event: K, payload: E[K]) => void {\n return useCallback(\n <K extends keyof E>(event: K, payload: E[K]) => {\n bus.emit(event, payload);\n },\n [bus]\n );\n}\n"],"names":["EventBus","useRef","useEffect","useCallback"],"mappings":";;;;AAOO,SAAS,SACd,QACA,OACA,SACM;AACN,QAAM,MAAM,kBAAkBA,SAAAA,WAAW,SAAS,OAAO;AAGzD,QAAM,aAAaC,MAAAA,OAAO,OAAO;AACjC,aAAW,UAAU;AAErBC,QAAAA,UAAU,MAAM;AACd,UAAM,cAAc,IAAI,GAAG,OAAO,CAAC,YAAY;AAC7C,iBAAW,QAAQ,OAAO;AAAA,IAC5B,CAAC;AAED,WAAO;AAAA,EACT,GAAG,CAAC,KAAK,KAAK,CAAC;AACjB;AAKO,SAAS,QACd,KACsD;AACtD,SAAOC,MAAAA;AAAAA,IACL,CAAoB,OAAU,YAAkB;AAC9C,UAAI,KAAK,OAAO,OAAO;AAAA,IACzB;AAAA,IACA,CAAC,GAAG;AAAA,EAAA;AAER;;;"}
1
+ {"version":3,"file":"use-event-bus.cjs","names":[],"sources":["../../src/react/use-event-bus.ts"],"sourcesContent":["import { useEffect, useCallback, useRef } from 'react';\nimport { EventBus } from '../EventBus';\n\n/**\n * Subscribe to a typed event, auto-unsubscribes on unmount.\n * Accepts an EventBus directly or any object with an `events` property (e.g. a ViewModel).\n */\nexport function useEvent<E extends Record<string, any>, K extends keyof E>(\n source: EventBus<E> | { events: EventBus<E> },\n event: K,\n handler: (payload: E[K]) => void\n): void {\n const bus = source instanceof EventBus ? source : source.events;\n\n // Use ref to keep handler stable across re-renders\n const handlerRef = useRef(handler);\n handlerRef.current = handler;\n\n useEffect(() => {\n const unsubscribe = bus.on(event, (payload) => {\n handlerRef.current(payload);\n });\n\n return unsubscribe;\n }, [bus, event]);\n}\n\n/**\n * Get a stable emit function for an EventBus.\n */\nexport function useEmit<E extends Record<string, any>>(\n bus: EventBus<E>\n): <K extends keyof E>(event: K, payload: E[K]) => void {\n return useCallback(\n <K extends keyof E>(event: K, payload: E[K]) => {\n bus.emit(event, payload);\n },\n [bus]\n );\n}\n"],"mappings":";;;;;;;AAOA,SAAgB,SACd,QACA,OACA,SACM;CACN,MAAM,MAAM,kBAAkB,iBAAA,WAAW,SAAS,OAAO;CAGzD,MAAM,cAAA,GAAA,MAAA,QAAoB,QAAQ;AAClC,YAAW,UAAU;AAErB,EAAA,GAAA,MAAA,iBAAgB;AAKd,SAJoB,IAAI,GAAG,QAAQ,YAAY;AAC7C,cAAW,QAAQ,QAAQ;IAC3B;IAGD,CAAC,KAAK,MAAM,CAAC;;;;;AAMlB,SAAgB,QACd,KACsD;AACtD,SAAA,GAAA,MAAA,cACsB,OAAU,YAAkB;AAC9C,MAAI,KAAK,OAAO,QAAQ;IAE1B,CAAC,IAAI,CACN"}
@@ -1,26 +1,29 @@
1
- import { useCallback, useRef, useEffect } from "react";
2
1
  import { EventBus } from "../EventBus.js";
2
+ import { useCallback, useEffect, useRef } from "react";
3
+ //#region src/react/use-event-bus.ts
4
+ /**
5
+ * Subscribe to a typed event, auto-unsubscribes on unmount.
6
+ * Accepts an EventBus directly or any object with an `events` property (e.g. a ViewModel).
7
+ */
3
8
  function useEvent(source, event, handler) {
4
- const bus = source instanceof EventBus ? source : source.events;
5
- const handlerRef = useRef(handler);
6
- handlerRef.current = handler;
7
- useEffect(() => {
8
- const unsubscribe = bus.on(event, (payload) => {
9
- handlerRef.current(payload);
10
- });
11
- return unsubscribe;
12
- }, [bus, event]);
9
+ const bus = source instanceof EventBus ? source : source.events;
10
+ const handlerRef = useRef(handler);
11
+ handlerRef.current = handler;
12
+ useEffect(() => {
13
+ return bus.on(event, (payload) => {
14
+ handlerRef.current(payload);
15
+ });
16
+ }, [bus, event]);
13
17
  }
18
+ /**
19
+ * Get a stable emit function for an EventBus.
20
+ */
14
21
  function useEmit(bus) {
15
- return useCallback(
16
- (event, payload) => {
17
- bus.emit(event, payload);
18
- },
19
- [bus]
20
- );
22
+ return useCallback((event, payload) => {
23
+ bus.emit(event, payload);
24
+ }, [bus]);
21
25
  }
22
- export {
23
- useEmit,
24
- useEvent
25
- };
26
- //# sourceMappingURL=use-event-bus.js.map
26
+ //#endregion
27
+ export { useEmit, useEvent };
28
+
29
+ //# sourceMappingURL=use-event-bus.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-event-bus.js","sources":["../../src/react/use-event-bus.ts"],"sourcesContent":["import { useEffect, useCallback, useRef } from 'react';\nimport { EventBus } from '../EventBus';\n\n/**\n * Subscribe to a typed event, auto-unsubscribes on unmount.\n * Accepts an EventBus directly or any object with an `events` property (e.g. a ViewModel).\n */\nexport function useEvent<E extends Record<string, any>, K extends keyof E>(\n source: EventBus<E> | { events: EventBus<E> },\n event: K,\n handler: (payload: E[K]) => void\n): void {\n const bus = source instanceof EventBus ? source : source.events;\n\n // Use ref to keep handler stable across re-renders\n const handlerRef = useRef(handler);\n handlerRef.current = handler;\n\n useEffect(() => {\n const unsubscribe = bus.on(event, (payload) => {\n handlerRef.current(payload);\n });\n\n return unsubscribe;\n }, [bus, event]);\n}\n\n/**\n * Get a stable emit function for an EventBus.\n */\nexport function useEmit<E extends Record<string, any>>(\n bus: EventBus<E>\n): <K extends keyof E>(event: K, payload: E[K]) => void {\n return useCallback(\n <K extends keyof E>(event: K, payload: E[K]) => {\n bus.emit(event, payload);\n },\n [bus]\n );\n}\n"],"names":[],"mappings":";;AAOO,SAAS,SACd,QACA,OACA,SACM;AACN,QAAM,MAAM,kBAAkB,WAAW,SAAS,OAAO;AAGzD,QAAM,aAAa,OAAO,OAAO;AACjC,aAAW,UAAU;AAErB,YAAU,MAAM;AACd,UAAM,cAAc,IAAI,GAAG,OAAO,CAAC,YAAY;AAC7C,iBAAW,QAAQ,OAAO;AAAA,IAC5B,CAAC;AAED,WAAO;AAAA,EACT,GAAG,CAAC,KAAK,KAAK,CAAC;AACjB;AAKO,SAAS,QACd,KACsD;AACtD,SAAO;AAAA,IACL,CAAoB,OAAU,YAAkB;AAC9C,UAAI,KAAK,OAAO,OAAO;AAAA,IACzB;AAAA,IACA,CAAC,GAAG;AAAA,EAAA;AAER;"}
1
+ {"version":3,"file":"use-event-bus.js","names":[],"sources":["../../src/react/use-event-bus.ts"],"sourcesContent":["import { useEffect, useCallback, useRef } from 'react';\nimport { EventBus } from '../EventBus';\n\n/**\n * Subscribe to a typed event, auto-unsubscribes on unmount.\n * Accepts an EventBus directly or any object with an `events` property (e.g. a ViewModel).\n */\nexport function useEvent<E extends Record<string, any>, K extends keyof E>(\n source: EventBus<E> | { events: EventBus<E> },\n event: K,\n handler: (payload: E[K]) => void\n): void {\n const bus = source instanceof EventBus ? source : source.events;\n\n // Use ref to keep handler stable across re-renders\n const handlerRef = useRef(handler);\n handlerRef.current = handler;\n\n useEffect(() => {\n const unsubscribe = bus.on(event, (payload) => {\n handlerRef.current(payload);\n });\n\n return unsubscribe;\n }, [bus, event]);\n}\n\n/**\n * Get a stable emit function for an EventBus.\n */\nexport function useEmit<E extends Record<string, any>>(\n bus: EventBus<E>\n): <K extends keyof E>(event: K, payload: E[K]) => void {\n return useCallback(\n <K extends keyof E>(event: K, payload: E[K]) => {\n bus.emit(event, payload);\n },\n [bus]\n );\n}\n"],"mappings":";;;;;;;AAOA,SAAgB,SACd,QACA,OACA,SACM;CACN,MAAM,MAAM,kBAAkB,WAAW,SAAS,OAAO;CAGzD,MAAM,aAAa,OAAO,QAAQ;AAClC,YAAW,UAAU;AAErB,iBAAgB;AAKd,SAJoB,IAAI,GAAG,QAAQ,YAAY;AAC7C,cAAW,QAAQ,QAAQ;IAC3B;IAGD,CAAC,KAAK,MAAM,CAAC;;;;;AAMlB,SAAgB,QACd,KACsD;AACtD,QAAO,aACe,OAAU,YAAkB;AAC9C,MAAI,KAAK,OAAO,QAAQ;IAE1B,CAAC,IAAI,CACN"}
@@ -1,41 +1,48 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const react = require("react");
1
+ let react = require("react");
2
+ //#region src/react/use-instance.ts
4
3
  function hasAsyncSubscription(obj) {
5
- return obj !== null && typeof obj === "object" && typeof obj.subscribeAsync === "function";
4
+ return obj !== null && typeof obj === "object" && typeof obj.subscribeAsync === "function";
6
5
  }
7
- const SERVER_SNAPSHOT = () => 0;
6
+ var SERVER_SNAPSHOT = () => 0;
7
+ /**
8
+ * Subscribe to an existing Subscribable instance.
9
+ * No ownership - caller manages the instance lifecycle.
10
+ *
11
+ * If the instance has a `subscribeAsync` method (duck-typed),
12
+ * a combined subscription ensures async state changes also
13
+ * trigger React re-renders.
14
+ */
8
15
  function useInstance(subscribable) {
9
- const ref = react.useRef(null);
10
- if (!ref.current || ref.current.subscribable !== subscribable) {
11
- const version = { current: ref.current?.version ?? 0 };
12
- ref.current = {
13
- version: version.current,
14
- subscribable,
15
- subscribe: (onStoreChange) => {
16
- const unsub1 = subscribable.subscribe(() => {
17
- version.current++;
18
- ref.current.version = version.current;
19
- onStoreChange();
20
- });
21
- let unsub2;
22
- if (hasAsyncSubscription(subscribable)) {
23
- unsub2 = subscribable.subscribeAsync(() => {
24
- version.current++;
25
- ref.current.version = version.current;
26
- onStoreChange();
27
- });
28
- }
29
- return () => {
30
- unsub1();
31
- unsub2?.();
32
- };
33
- },
34
- getSnapshot: () => version.current
35
- };
36
- }
37
- react.useSyncExternalStore(ref.current.subscribe, ref.current.getSnapshot, SERVER_SNAPSHOT);
38
- return subscribable.state;
16
+ const ref = (0, react.useRef)(null);
17
+ if (!ref.current || ref.current.subscribable !== subscribable) {
18
+ const version = { current: ref.current?.version ?? 0 };
19
+ ref.current = {
20
+ version: version.current,
21
+ subscribable,
22
+ subscribe: (onStoreChange) => {
23
+ const unsub1 = subscribable.subscribe(() => {
24
+ version.current++;
25
+ ref.current.version = version.current;
26
+ onStoreChange();
27
+ });
28
+ let unsub2;
29
+ if (hasAsyncSubscription(subscribable)) unsub2 = subscribable.subscribeAsync(() => {
30
+ version.current++;
31
+ ref.current.version = version.current;
32
+ onStoreChange();
33
+ });
34
+ return () => {
35
+ unsub1();
36
+ unsub2?.();
37
+ };
38
+ },
39
+ getSnapshot: () => version.current
40
+ };
41
+ }
42
+ (0, react.useSyncExternalStore)(ref.current.subscribe, ref.current.getSnapshot, SERVER_SNAPSHOT);
43
+ return subscribable.state;
39
44
  }
45
+ //#endregion
40
46
  exports.useInstance = useInstance;
41
- //# sourceMappingURL=use-instance.cjs.map
47
+
48
+ //# sourceMappingURL=use-instance.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-instance.cjs","sources":["../../src/react/use-instance.ts"],"sourcesContent":["import { useSyncExternalStore, useRef } from 'react';\nimport type { Subscribable } from '../types';\n\nfunction hasAsyncSubscription(obj: unknown): obj is { subscribeAsync(cb: () => void): () => void } {\n return (\n obj !== null &&\n typeof obj === 'object' &&\n typeof (obj as any).subscribeAsync === 'function'\n );\n}\n\nconst SERVER_SNAPSHOT = () => 0;\n\ninterface InstanceRef<S> {\n version: number;\n subscribable: Subscribable<S>;\n subscribe: (onStoreChange: () => void) => () => void;\n getSnapshot: () => number;\n}\n\n/**\n * Subscribe to an existing Subscribable instance.\n * No ownership - caller manages the instance lifecycle.\n *\n * If the instance has a `subscribeAsync` method (duck-typed),\n * a combined subscription ensures async state changes also\n * trigger React re-renders.\n */\nexport function useInstance<S>(subscribable: Subscribable<S>): S {\n const ref = useRef<InstanceRef<S> | null>(null);\n\n if (!ref.current || ref.current.subscribable !== subscribable) {\n const version = { current: ref.current?.version ?? 0 };\n ref.current = {\n version: version.current,\n subscribable,\n subscribe: (onStoreChange: () => void) => {\n const unsub1 = subscribable.subscribe(() => {\n version.current++;\n ref.current!.version = version.current;\n onStoreChange();\n });\n let unsub2: (() => void) | undefined;\n if (hasAsyncSubscription(subscribable)) {\n unsub2 = subscribable.subscribeAsync(() => {\n version.current++;\n ref.current!.version = version.current;\n onStoreChange();\n });\n }\n return () => { unsub1(); unsub2?.(); };\n },\n getSnapshot: () => version.current,\n };\n }\n\n useSyncExternalStore(ref.current.subscribe, ref.current.getSnapshot, SERVER_SNAPSHOT);\n\n return subscribable.state;\n}\n"],"names":["useRef","useSyncExternalStore"],"mappings":";;;AAGA,SAAS,qBAAqB,KAAqE;AACjG,SACE,QAAQ,QACR,OAAO,QAAQ,YACf,OAAQ,IAAY,mBAAmB;AAE3C;AAEA,MAAM,kBAAkB,MAAM;AAiBvB,SAAS,YAAe,cAAkC;AAC/D,QAAM,MAAMA,MAAAA,OAA8B,IAAI;AAE9C,MAAI,CAAC,IAAI,WAAW,IAAI,QAAQ,iBAAiB,cAAc;AAC7D,UAAM,UAAU,EAAE,SAAS,IAAI,SAAS,WAAW,EAAA;AACnD,QAAI,UAAU;AAAA,MACZ,SAAS,QAAQ;AAAA,MACjB;AAAA,MACA,WAAW,CAAC,kBAA8B;AACxC,cAAM,SAAS,aAAa,UAAU,MAAM;AAC1C,kBAAQ;AACR,cAAI,QAAS,UAAU,QAAQ;AAC/B,wBAAA;AAAA,QACF,CAAC;AACD,YAAI;AACJ,YAAI,qBAAqB,YAAY,GAAG;AACtC,mBAAS,aAAa,eAAe,MAAM;AACzC,oBAAQ;AACR,gBAAI,QAAS,UAAU,QAAQ;AAC/B,0BAAA;AAAA,UACF,CAAC;AAAA,QACH;AACA,eAAO,MAAM;AAAE,iBAAA;AAAU,mBAAA;AAAA,QAAY;AAAA,MACvC;AAAA,MACA,aAAa,MAAM,QAAQ;AAAA,IAAA;AAAA,EAE/B;AAEAC,QAAAA,qBAAqB,IAAI,QAAQ,WAAW,IAAI,QAAQ,aAAa,eAAe;AAEpF,SAAO,aAAa;AACtB;;"}
1
+ {"version":3,"file":"use-instance.cjs","names":[],"sources":["../../src/react/use-instance.ts"],"sourcesContent":["import { useSyncExternalStore, useRef } from 'react';\nimport type { Subscribable } from '../types';\n\nfunction hasAsyncSubscription(obj: unknown): obj is { subscribeAsync(cb: () => void): () => void } {\n return (\n obj !== null &&\n typeof obj === 'object' &&\n typeof (obj as any).subscribeAsync === 'function'\n );\n}\n\nconst SERVER_SNAPSHOT = () => 0;\n\ninterface InstanceRef<S> {\n version: number;\n subscribable: Subscribable<S>;\n subscribe: (onStoreChange: () => void) => () => void;\n getSnapshot: () => number;\n}\n\n/**\n * Subscribe to an existing Subscribable instance.\n * No ownership - caller manages the instance lifecycle.\n *\n * If the instance has a `subscribeAsync` method (duck-typed),\n * a combined subscription ensures async state changes also\n * trigger React re-renders.\n */\nexport function useInstance<S>(subscribable: Subscribable<S>): S {\n const ref = useRef<InstanceRef<S> | null>(null);\n\n if (!ref.current || ref.current.subscribable !== subscribable) {\n const version = { current: ref.current?.version ?? 0 };\n ref.current = {\n version: version.current,\n subscribable,\n subscribe: (onStoreChange: () => void) => {\n const unsub1 = subscribable.subscribe(() => {\n version.current++;\n ref.current!.version = version.current;\n onStoreChange();\n });\n let unsub2: (() => void) | undefined;\n if (hasAsyncSubscription(subscribable)) {\n unsub2 = subscribable.subscribeAsync(() => {\n version.current++;\n ref.current!.version = version.current;\n onStoreChange();\n });\n }\n return () => { unsub1(); unsub2?.(); };\n },\n getSnapshot: () => version.current,\n };\n }\n\n useSyncExternalStore(ref.current.subscribe, ref.current.getSnapshot, SERVER_SNAPSHOT);\n\n return subscribable.state;\n}\n"],"mappings":";;AAGA,SAAS,qBAAqB,KAAqE;AACjG,QACE,QAAQ,QACR,OAAO,QAAQ,YACf,OAAQ,IAAY,mBAAmB;;AAI3C,IAAM,wBAAwB;;;;;;;;;AAiB9B,SAAgB,YAAe,cAAkC;CAC/D,MAAM,OAAA,GAAA,MAAA,QAAoC,KAAK;AAE/C,KAAI,CAAC,IAAI,WAAW,IAAI,QAAQ,iBAAiB,cAAc;EAC7D,MAAM,UAAU,EAAE,SAAS,IAAI,SAAS,WAAW,GAAG;AACtD,MAAI,UAAU;GACZ,SAAS,QAAQ;GACjB;GACA,YAAY,kBAA8B;IACxC,MAAM,SAAS,aAAa,gBAAgB;AAC1C,aAAQ;AACR,SAAI,QAAS,UAAU,QAAQ;AAC/B,oBAAe;MACf;IACF,IAAI;AACJ,QAAI,qBAAqB,aAAa,CACpC,UAAS,aAAa,qBAAqB;AACzC,aAAQ;AACR,SAAI,QAAS,UAAU,QAAQ;AAC/B,oBAAe;MACf;AAEJ,iBAAa;AAAE,aAAQ;AAAE,eAAU;;;GAErC,mBAAmB,QAAQ;GAC5B;;AAGH,EAAA,GAAA,MAAA,sBAAqB,IAAI,QAAQ,WAAW,IAAI,QAAQ,aAAa,gBAAgB;AAErF,QAAO,aAAa"}