mvc-kit 2.12.4 → 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.
- package/agent-config/bin/postinstall.mjs +4 -3
- package/agent-config/bin/setup.mjs +5 -1
- package/agent-config/claude-code/agents/mvc-kit-architect.md +11 -8
- package/agent-config/claude-code/skills/guide/SKILL.md +20 -7
- package/agent-config/claude-code/skills/guide/patterns.md +12 -0
- package/agent-config/claude-code/skills/guide/recipes.md +510 -0
- package/agent-config/claude-code/skills/guide/testing.md +297 -0
- package/agent-config/claude-code/skills/review/SKILL.md +3 -13
- package/agent-config/claude-code/skills/review/checklist.md +30 -5
- package/agent-config/claude-code/skills/scaffold/SKILL.md +4 -13
- package/agent-config/lib/install-claude.mjs +84 -25
- package/dist/Channel.cjs +276 -300
- package/dist/Channel.cjs.map +1 -1
- package/dist/Channel.js +275 -299
- package/dist/Channel.js.map +1 -1
- package/dist/Collection.cjs +424 -504
- package/dist/Collection.cjs.map +1 -1
- package/dist/Collection.js +423 -503
- package/dist/Collection.js.map +1 -1
- package/dist/Controller.cjs +70 -67
- package/dist/Controller.cjs.map +1 -1
- package/dist/Controller.js +69 -66
- package/dist/Controller.js.map +1 -1
- package/dist/EventBus.cjs +77 -88
- package/dist/EventBus.cjs.map +1 -1
- package/dist/EventBus.js +76 -87
- package/dist/EventBus.js.map +1 -1
- package/dist/Feed.cjs +81 -77
- package/dist/Feed.cjs.map +1 -1
- package/dist/Feed.js +80 -76
- package/dist/Feed.js.map +1 -1
- package/dist/Model.cjs +181 -207
- package/dist/Model.cjs.map +1 -1
- package/dist/Model.js +179 -205
- package/dist/Model.js.map +1 -1
- package/dist/Pagination.cjs +75 -73
- package/dist/Pagination.cjs.map +1 -1
- package/dist/Pagination.js +74 -72
- package/dist/Pagination.js.map +1 -1
- package/dist/Pending.cjs +255 -287
- package/dist/Pending.cjs.map +1 -1
- package/dist/Pending.js +253 -285
- package/dist/Pending.js.map +1 -1
- package/dist/PersistentCollection.cjs +242 -285
- package/dist/PersistentCollection.cjs.map +1 -1
- package/dist/PersistentCollection.js +241 -284
- package/dist/PersistentCollection.js.map +1 -1
- package/dist/Resource.cjs +166 -174
- package/dist/Resource.cjs.map +1 -1
- package/dist/Resource.js +164 -172
- package/dist/Resource.js.map +1 -1
- package/dist/Selection.cjs +84 -94
- package/dist/Selection.cjs.map +1 -1
- package/dist/Selection.js +83 -93
- package/dist/Selection.js.map +1 -1
- package/dist/Service.cjs +54 -55
- package/dist/Service.cjs.map +1 -1
- package/dist/Service.js +53 -54
- package/dist/Service.js.map +1 -1
- package/dist/Sorting.cjs +102 -101
- package/dist/Sorting.cjs.map +1 -1
- package/dist/Sorting.js +102 -101
- package/dist/Sorting.js.map +1 -1
- package/dist/Trackable.cjs +112 -80
- package/dist/Trackable.cjs.map +1 -1
- package/dist/Trackable.js +111 -79
- package/dist/Trackable.js.map +1 -1
- package/dist/ViewModel.cjs +528 -576
- package/dist/ViewModel.cjs.map +1 -1
- package/dist/ViewModel.js +525 -573
- package/dist/ViewModel.js.map +1 -1
- package/dist/bindPublicMethods.cjs +43 -24
- package/dist/bindPublicMethods.cjs.map +1 -1
- package/dist/bindPublicMethods.js +43 -24
- package/dist/bindPublicMethods.js.map +1 -1
- package/dist/errors.cjs +67 -68
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.js +68 -71
- package/dist/errors.js.map +1 -1
- package/dist/mvc-kit.cjs +44 -46
- package/dist/mvc-kit.js +5 -32
- package/dist/produceDraft.cjs +105 -95
- package/dist/produceDraft.cjs.map +1 -1
- package/dist/produceDraft.js +106 -97
- package/dist/produceDraft.js.map +1 -1
- package/dist/react/components/CardList.cjs +30 -40
- package/dist/react/components/CardList.cjs.map +1 -1
- package/dist/react/components/CardList.js +31 -41
- package/dist/react/components/CardList.js.map +1 -1
- package/dist/react/components/DataTable.cjs +146 -169
- package/dist/react/components/DataTable.cjs.map +1 -1
- package/dist/react/components/DataTable.js +147 -170
- package/dist/react/components/DataTable.js.map +1 -1
- package/dist/react/components/InfiniteScroll.cjs +51 -42
- package/dist/react/components/InfiniteScroll.cjs.map +1 -1
- package/dist/react/components/InfiniteScroll.js +52 -43
- package/dist/react/components/InfiniteScroll.js.map +1 -1
- package/dist/react/components/types.cjs +10 -6
- package/dist/react/components/types.cjs.map +1 -1
- package/dist/react/components/types.js +11 -9
- package/dist/react/components/types.js.map +1 -1
- package/dist/react/guards.cjs +10 -6
- package/dist/react/guards.cjs.map +1 -1
- package/dist/react/guards.js +11 -9
- package/dist/react/guards.js.map +1 -1
- package/dist/react/provider.cjs +23 -20
- package/dist/react/provider.cjs.map +1 -1
- package/dist/react/provider.js +23 -21
- package/dist/react/provider.js.map +1 -1
- package/dist/react/use-event-bus.cjs +24 -20
- package/dist/react/use-event-bus.cjs.map +1 -1
- package/dist/react/use-event-bus.js +24 -21
- package/dist/react/use-event-bus.js.map +1 -1
- package/dist/react/use-instance.cjs +43 -36
- package/dist/react/use-instance.cjs.map +1 -1
- package/dist/react/use-instance.js +43 -36
- package/dist/react/use-instance.js.map +1 -1
- package/dist/react/use-local.cjs +48 -64
- package/dist/react/use-local.cjs.map +1 -1
- package/dist/react/use-local.js +47 -63
- package/dist/react/use-local.js.map +1 -1
- package/dist/react/use-model.cjs +84 -98
- package/dist/react/use-model.cjs.map +1 -1
- package/dist/react/use-model.js +84 -100
- package/dist/react/use-model.js.map +1 -1
- package/dist/react/use-singleton.cjs +19 -23
- package/dist/react/use-singleton.cjs.map +1 -1
- package/dist/react/use-singleton.js +16 -20
- package/dist/react/use-singleton.js.map +1 -1
- package/dist/react/use-subscribe-only.cjs +28 -22
- package/dist/react/use-subscribe-only.cjs.map +1 -1
- package/dist/react/use-subscribe-only.js +28 -22
- package/dist/react/use-subscribe-only.js.map +1 -1
- package/dist/react/use-teardown.cjs +20 -19
- package/dist/react/use-teardown.cjs.map +1 -1
- package/dist/react/use-teardown.js +20 -19
- package/dist/react/use-teardown.js.map +1 -1
- package/dist/react-native/NativeCollection.cjs +98 -78
- package/dist/react-native/NativeCollection.cjs.map +1 -1
- package/dist/react-native/NativeCollection.js +97 -77
- package/dist/react-native/NativeCollection.js.map +1 -1
- package/dist/react-native.cjs +2 -4
- package/dist/react-native.js +1 -4
- package/dist/react.cjs +24 -26
- package/dist/react.js +1 -17
- package/dist/singleton.cjs +28 -22
- package/dist/singleton.cjs.map +1 -1
- package/dist/singleton.js +29 -26
- package/dist/singleton.js.map +1 -1
- package/dist/walkPrototypeChain.cjs +20 -12
- package/dist/walkPrototypeChain.cjs.map +1 -1
- package/dist/walkPrototypeChain.js +21 -13
- package/dist/walkPrototypeChain.js.map +1 -1
- package/dist/web/IndexedDBCollection.cjs +53 -36
- package/dist/web/IndexedDBCollection.cjs.map +1 -1
- package/dist/web/IndexedDBCollection.js +52 -35
- package/dist/web/IndexedDBCollection.js.map +1 -1
- package/dist/web/WebStorageCollection.cjs +82 -84
- package/dist/web/WebStorageCollection.cjs.map +1 -1
- package/dist/web/WebStorageCollection.js +81 -83
- package/dist/web/WebStorageCollection.js.map +1 -1
- package/dist/web/idb.cjs +107 -99
- package/dist/web/idb.cjs.map +1 -1
- package/dist/web/idb.js +108 -105
- package/dist/web/idb.js.map +1 -1
- package/dist/web.cjs +4 -6
- package/dist/web.js +1 -5
- package/dist/wrapAsyncMethods.cjs +141 -168
- package/dist/wrapAsyncMethods.cjs.map +1 -1
- package/dist/wrapAsyncMethods.js +141 -168
- package/dist/wrapAsyncMethods.js.map +1 -1
- package/package.json +8 -8
- package/src/Pending.test.ts +1 -2
- package/src/Sorting.test.ts +1 -1
- package/src/produceDraft.test.ts +3 -3
- package/src/react/components/CardList.test.tsx +1 -1
- package/src/react/components/DataTable.test.tsx +1 -1
- package/src/react/components/InfiniteScroll.test.tsx +5 -5
- package/dist/mvc-kit.cjs.map +0 -1
- package/dist/mvc-kit.js.map +0 -1
- package/dist/react-native.cjs.map +0 -1
- package/dist/react-native.js.map +0 -1
- package/dist/react.cjs.map +0 -1
- package/dist/react.js.map +0 -1
- package/dist/web.cjs.map +0 -1
- 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"],"
|
|
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
|
-
|
|
2
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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"],"
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
12
|
+
return s != null && !Array.isArray(s) && "sorts" in s && "toggle" in s;
|
|
9
13
|
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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"],"
|
|
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"}
|
package/dist/react/guards.cjs
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
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
|
-
|
|
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"],"
|
|
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"}
|
package/dist/react/guards.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
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
|
package/dist/react/guards.js.map
CHANGED
|
@@ -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"],"
|
|
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"}
|
package/dist/react/provider.cjs
CHANGED
|
@@ -1,26 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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
|
-
|
|
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"],"
|
|
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"}
|
package/dist/react/provider.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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"],"
|
|
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
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
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
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
-
|
|
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"],"
|
|
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
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
},
|
|
19
|
-
[bus]
|
|
20
|
-
);
|
|
22
|
+
return useCallback((event, payload) => {
|
|
23
|
+
bus.emit(event, payload);
|
|
24
|
+
}, [bus]);
|
|
21
25
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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"],"
|
|
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
|
-
|
|
2
|
-
|
|
3
|
-
const react = require("react");
|
|
1
|
+
let react = require("react");
|
|
2
|
+
//#region src/react/use-instance.ts
|
|
4
3
|
function hasAsyncSubscription(obj) {
|
|
5
|
-
|
|
4
|
+
return obj !== null && typeof obj === "object" && typeof obj.subscribeAsync === "function";
|
|
6
5
|
}
|
|
7
|
-
|
|
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
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|
-
|
|
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"],"
|
|
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"}
|