@fgv/ts-app-shell 5.1.0-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. package/README.md +26 -0
  2. package/dist/index.browser.js +3 -0
  3. package/dist/index.js +43 -0
  4. package/dist/packlets/ai-assist/index.js +6 -0
  5. package/dist/packlets/ai-assist/useAiAssist.js +219 -0
  6. package/dist/packlets/cascade/CascadeContainer.js +83 -0
  7. package/dist/packlets/cascade/ComparisonView.js +48 -0
  8. package/dist/packlets/cascade/EntityTabLayout.js +104 -0
  9. package/dist/packlets/cascade/MobileCascadeStack.js +63 -0
  10. package/dist/packlets/cascade/index.js +37 -0
  11. package/dist/packlets/cascade/model.js +30 -0
  12. package/dist/packlets/cascade/useCascadeOps.js +206 -0
  13. package/dist/packlets/cascade/useCascadeTransitions.js +58 -0
  14. package/dist/packlets/detail/DetailHelpers.js +103 -0
  15. package/dist/packlets/detail/index.js +6 -0
  16. package/dist/packlets/drop-zone/JsonDropZone.js +112 -0
  17. package/dist/packlets/drop-zone/index.js +6 -0
  18. package/dist/packlets/editing/EditFieldHelpers.js +130 -0
  19. package/dist/packlets/editing/MultiActionButton.js +73 -0
  20. package/dist/packlets/editing/NumericInput.js +119 -0
  21. package/dist/packlets/editing/TypeaheadInput.js +207 -0
  22. package/dist/packlets/editing/index.js +10 -0
  23. package/dist/packlets/editing/useTypeaheadMatch.js +102 -0
  24. package/dist/packlets/keyboard/index.js +7 -0
  25. package/dist/packlets/keyboard/registry.js +133 -0
  26. package/dist/packlets/keyboard/useKeyboardShortcuts.js +117 -0
  27. package/dist/packlets/messages/MessagesContext.js +76 -0
  28. package/dist/packlets/messages/MessagesLogger.js +103 -0
  29. package/dist/packlets/messages/StatusBar.js +154 -0
  30. package/dist/packlets/messages/Toast.js +68 -0
  31. package/dist/packlets/messages/index.js +11 -0
  32. package/dist/packlets/messages/model.js +56 -0
  33. package/dist/packlets/messages/useLogReporter.js +66 -0
  34. package/dist/packlets/modal/ConfirmDialog.js +78 -0
  35. package/dist/packlets/modal/Modal.js +55 -0
  36. package/dist/packlets/modal/index.js +7 -0
  37. package/dist/packlets/print/PrintEnclosure.js +60 -0
  38. package/dist/packlets/print/index.js +7 -0
  39. package/dist/packlets/print/openPrintWindow.js +112 -0
  40. package/dist/packlets/responsive/ResponsiveProvider.js +56 -0
  41. package/dist/packlets/responsive/index.js +7 -0
  42. package/dist/packlets/responsive/useResponsiveLayout.js +118 -0
  43. package/dist/packlets/selectors/EntityRow.js +276 -0
  44. package/dist/packlets/selectors/PreferredSelector.js +251 -0
  45. package/dist/packlets/selectors/index.js +24 -0
  46. package/dist/packlets/sidebar/CollectionSection.js +107 -0
  47. package/dist/packlets/sidebar/EntityList.js +164 -0
  48. package/dist/packlets/sidebar/FilterBar.js +42 -0
  49. package/dist/packlets/sidebar/FilterRow.js +182 -0
  50. package/dist/packlets/sidebar/GroupedEntityList.js +183 -0
  51. package/dist/packlets/sidebar/SearchBar.js +34 -0
  52. package/dist/packlets/sidebar/SidebarLayout.js +62 -0
  53. package/dist/packlets/sidebar/index.js +12 -0
  54. package/dist/packlets/theme/ThemeProvider.js +141 -0
  55. package/dist/packlets/theme/index.js +6 -0
  56. package/dist/packlets/top-bar/ModeSelector.js +46 -0
  57. package/dist/packlets/top-bar/TabBar.js +37 -0
  58. package/dist/packlets/top-bar/index.js +7 -0
  59. package/dist/packlets/url-sync/index.js +6 -0
  60. package/dist/packlets/url-sync/useUrlSync.js +157 -0
  61. package/eslint.config.js +22 -0
  62. package/lib/index.browser.d.ts +2 -0
  63. package/lib/index.browser.js +19 -0
  64. package/lib/index.d.ts +28 -0
  65. package/lib/index.js +59 -0
  66. package/lib/packlets/ai-assist/index.d.ts +6 -0
  67. package/lib/packlets/ai-assist/index.js +11 -0
  68. package/lib/packlets/ai-assist/useAiAssist.d.ts +77 -0
  69. package/lib/packlets/ai-assist/useAiAssist.js +223 -0
  70. package/lib/packlets/cascade/CascadeContainer.d.ts +44 -0
  71. package/lib/packlets/cascade/CascadeContainer.js +119 -0
  72. package/lib/packlets/cascade/ComparisonView.d.ts +35 -0
  73. package/lib/packlets/cascade/ComparisonView.js +54 -0
  74. package/lib/packlets/cascade/EntityTabLayout.d.ts +47 -0
  75. package/lib/packlets/cascade/EntityTabLayout.js +110 -0
  76. package/lib/packlets/cascade/MobileCascadeStack.d.ts +20 -0
  77. package/lib/packlets/cascade/MobileCascadeStack.js +99 -0
  78. package/lib/packlets/cascade/index.d.ts +12 -0
  79. package/lib/packlets/cascade/index.js +48 -0
  80. package/lib/packlets/cascade/model.d.ts +57 -0
  81. package/lib/packlets/cascade/model.js +33 -0
  82. package/lib/packlets/cascade/useCascadeOps.d.ts +111 -0
  83. package/lib/packlets/cascade/useCascadeOps.js +209 -0
  84. package/lib/packlets/cascade/useCascadeTransitions.d.ts +19 -0
  85. package/lib/packlets/cascade/useCascadeTransitions.js +62 -0
  86. package/lib/packlets/detail/DetailHelpers.d.ts +83 -0
  87. package/lib/packlets/detail/DetailHelpers.js +113 -0
  88. package/lib/packlets/detail/index.d.ts +6 -0
  89. package/lib/packlets/detail/index.js +14 -0
  90. package/lib/packlets/drop-zone/JsonDropZone.d.ts +40 -0
  91. package/lib/packlets/drop-zone/JsonDropZone.js +149 -0
  92. package/lib/packlets/drop-zone/index.d.ts +6 -0
  93. package/lib/packlets/drop-zone/index.js +10 -0
  94. package/lib/packlets/editing/EditFieldHelpers.d.ts +171 -0
  95. package/lib/packlets/editing/EditFieldHelpers.js +144 -0
  96. package/lib/packlets/editing/MultiActionButton.d.ts +45 -0
  97. package/lib/packlets/editing/MultiActionButton.js +109 -0
  98. package/lib/packlets/editing/NumericInput.d.ts +47 -0
  99. package/lib/packlets/editing/NumericInput.js +155 -0
  100. package/lib/packlets/editing/TypeaheadInput.d.ts +46 -0
  101. package/lib/packlets/editing/TypeaheadInput.js +243 -0
  102. package/lib/packlets/editing/index.d.ts +10 -0
  103. package/lib/packlets/editing/index.js +26 -0
  104. package/lib/packlets/editing/useTypeaheadMatch.d.ts +42 -0
  105. package/lib/packlets/editing/useTypeaheadMatch.js +105 -0
  106. package/lib/packlets/keyboard/index.d.ts +7 -0
  107. package/lib/packlets/keyboard/index.js +15 -0
  108. package/lib/packlets/keyboard/registry.d.ts +92 -0
  109. package/lib/packlets/keyboard/registry.js +138 -0
  110. package/lib/packlets/keyboard/useKeyboardShortcuts.d.ts +50 -0
  111. package/lib/packlets/keyboard/useKeyboardShortcuts.js +155 -0
  112. package/lib/packlets/messages/MessagesContext.d.ts +40 -0
  113. package/lib/packlets/messages/MessagesContext.js +113 -0
  114. package/lib/packlets/messages/MessagesLogger.d.ts +50 -0
  115. package/lib/packlets/messages/MessagesLogger.js +107 -0
  116. package/lib/packlets/messages/StatusBar.d.ts +22 -0
  117. package/lib/packlets/messages/StatusBar.js +190 -0
  118. package/lib/packlets/messages/Toast.d.ts +31 -0
  119. package/lib/packlets/messages/Toast.js +105 -0
  120. package/lib/packlets/messages/index.d.ts +11 -0
  121. package/lib/packlets/messages/index.js +24 -0
  122. package/lib/packlets/messages/model.d.ts +59 -0
  123. package/lib/packlets/messages/model.js +61 -0
  124. package/lib/packlets/messages/useLogReporter.d.ts +22 -0
  125. package/lib/packlets/messages/useLogReporter.js +69 -0
  126. package/lib/packlets/modal/ConfirmDialog.d.ts +39 -0
  127. package/lib/packlets/modal/ConfirmDialog.js +114 -0
  128. package/lib/packlets/modal/Modal.d.ts +22 -0
  129. package/lib/packlets/modal/Modal.js +91 -0
  130. package/lib/packlets/modal/index.d.ts +7 -0
  131. package/lib/packlets/modal/index.js +12 -0
  132. package/lib/packlets/print/PrintEnclosure.d.ts +33 -0
  133. package/lib/packlets/print/PrintEnclosure.js +96 -0
  134. package/lib/packlets/print/index.d.ts +7 -0
  135. package/lib/packlets/print/index.js +12 -0
  136. package/lib/packlets/print/openPrintWindow.d.ts +35 -0
  137. package/lib/packlets/print/openPrintWindow.js +118 -0
  138. package/lib/packlets/responsive/ResponsiveProvider.d.ts +35 -0
  139. package/lib/packlets/responsive/ResponsiveProvider.js +93 -0
  140. package/lib/packlets/responsive/index.d.ts +7 -0
  141. package/lib/packlets/responsive/index.js +13 -0
  142. package/lib/packlets/responsive/useResponsiveLayout.d.ts +48 -0
  143. package/lib/packlets/responsive/useResponsiveLayout.js +121 -0
  144. package/lib/packlets/selectors/EntityRow.d.ts +45 -0
  145. package/lib/packlets/selectors/EntityRow.js +315 -0
  146. package/lib/packlets/selectors/PreferredSelector.d.ts +50 -0
  147. package/lib/packlets/selectors/PreferredSelector.js +287 -0
  148. package/lib/packlets/selectors/index.d.ts +5 -0
  149. package/lib/packlets/selectors/index.js +29 -0
  150. package/lib/packlets/sidebar/CollectionSection.d.ts +82 -0
  151. package/lib/packlets/sidebar/CollectionSection.js +143 -0
  152. package/lib/packlets/sidebar/EntityList.d.ts +105 -0
  153. package/lib/packlets/sidebar/EntityList.js +200 -0
  154. package/lib/packlets/sidebar/FilterBar.d.ts +26 -0
  155. package/lib/packlets/sidebar/FilterBar.js +48 -0
  156. package/lib/packlets/sidebar/FilterRow.d.ts +42 -0
  157. package/lib/packlets/sidebar/FilterRow.js +218 -0
  158. package/lib/packlets/sidebar/GroupedEntityList.d.ts +59 -0
  159. package/lib/packlets/sidebar/GroupedEntityList.js +219 -0
  160. package/lib/packlets/sidebar/SearchBar.d.ts +19 -0
  161. package/lib/packlets/sidebar/SearchBar.js +40 -0
  162. package/lib/packlets/sidebar/SidebarLayout.d.ts +28 -0
  163. package/lib/packlets/sidebar/SidebarLayout.js +98 -0
  164. package/lib/packlets/sidebar/index.d.ts +12 -0
  165. package/lib/packlets/sidebar/index.js +22 -0
  166. package/lib/packlets/theme/ThemeProvider.d.ts +68 -0
  167. package/lib/packlets/theme/ThemeProvider.js +178 -0
  168. package/lib/packlets/theme/index.d.ts +6 -0
  169. package/lib/packlets/theme/index.js +11 -0
  170. package/lib/packlets/top-bar/ModeSelector.d.ts +38 -0
  171. package/lib/packlets/top-bar/ModeSelector.js +52 -0
  172. package/lib/packlets/top-bar/TabBar.d.ts +31 -0
  173. package/lib/packlets/top-bar/TabBar.js +43 -0
  174. package/lib/packlets/top-bar/index.d.ts +7 -0
  175. package/lib/packlets/top-bar/index.js +12 -0
  176. package/lib/packlets/url-sync/index.d.ts +6 -0
  177. package/lib/packlets/url-sync/index.js +12 -0
  178. package/lib/packlets/url-sync/useUrlSync.d.ts +75 -0
  179. package/lib/packlets/url-sync/useUrlSync.js +162 -0
  180. package/package.json +82 -0
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright (c) 2026 Erik Fortune
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ * of this software and associated documentation files (the "Software"), to deal
7
+ * in the Software without restriction, including without limitation the rights
8
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ * copies of the Software, and to permit persons to whom the Software is
10
+ * furnished to do so, subject to the following conditions:
11
+ *
12
+ * The above copyright notice and this permission notice shall be included in all
13
+ * copies or substantial portions of the Software.
14
+ *
15
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ * SOFTWARE.
22
+ */
23
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
24
+ if (k2 === undefined) k2 = k;
25
+ var desc = Object.getOwnPropertyDescriptor(m, k);
26
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
27
+ desc = { enumerable: true, get: function() { return m[k]; } };
28
+ }
29
+ Object.defineProperty(o, k2, desc);
30
+ }) : (function(o, m, k, k2) {
31
+ if (k2 === undefined) k2 = k;
32
+ o[k2] = m[k];
33
+ }));
34
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
35
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
36
+ }) : function(o, v) {
37
+ o["default"] = v;
38
+ });
39
+ var __importStar = (this && this.__importStar) || (function () {
40
+ var ownKeys = function(o) {
41
+ ownKeys = Object.getOwnPropertyNames || function (o) {
42
+ var ar = [];
43
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
44
+ return ar;
45
+ };
46
+ return ownKeys(o);
47
+ };
48
+ return function (mod) {
49
+ if (mod && mod.__esModule) return mod;
50
+ var result = {};
51
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
52
+ __setModuleDefault(result, mod);
53
+ return result;
54
+ };
55
+ })();
56
+ Object.defineProperty(exports, "__esModule", { value: true });
57
+ exports.CascadeContainer = CascadeContainer;
58
+ /**
59
+ * Column cascade container — horizontal scroll of detail columns.
60
+ * @packageDocumentation
61
+ */
62
+ const react_1 = __importStar(require("react"));
63
+ const responsive_1 = require("../responsive");
64
+ const MobileCascadeStack_1 = require("./MobileCascadeStack");
65
+ // ============================================================================
66
+ // CascadeContainer Component
67
+ // ============================================================================
68
+ /**
69
+ * Horizontal scroll container for the column cascade.
70
+ *
71
+ * Renders a breadcrumb trail at the top and horizontally-scrollable
72
+ * detail columns below. Auto-scrolls to the rightmost column when
73
+ * a new column is pushed.
74
+ *
75
+ * @public
76
+ */
77
+ function CascadeContainer(props) {
78
+ const { columns, onPopTo, minColumnWidth = '400px', onFocus, rootLabel = 'List' } = props;
79
+ const { layoutMode } = (0, responsive_1.useResponsive)();
80
+ const scrollRef = (0, react_1.useRef)(null);
81
+ const handleMouseDown = (0, react_1.useCallback)(() => {
82
+ onFocus === null || onFocus === void 0 ? void 0 : onFocus();
83
+ }, [onFocus]);
84
+ const handleKeyDown = (0, react_1.useCallback)((e) => {
85
+ if (e.key === 'Escape' || e.key === 'ArrowLeft') {
86
+ e.preventDefault();
87
+ e.stopPropagation();
88
+ if (columns.length > 1) {
89
+ onPopTo(columns.length - 1);
90
+ }
91
+ else {
92
+ onPopTo(0);
93
+ }
94
+ }
95
+ }, [columns.length, onPopTo]);
96
+ // Auto-scroll to rightmost column when columns change
97
+ (0, react_1.useEffect)(() => {
98
+ if (scrollRef.current) {
99
+ scrollRef.current.scrollTo({
100
+ left: scrollRef.current.scrollWidth,
101
+ behavior: 'smooth'
102
+ });
103
+ }
104
+ }, [columns.length]);
105
+ if (layoutMode === 'mobile') {
106
+ return react_1.default.createElement(MobileCascadeStack_1.MobileCascadeStack, Object.assign({}, props));
107
+ }
108
+ if (columns.length === 0) {
109
+ return null;
110
+ }
111
+ return (react_1.default.createElement("div", { className: "flex flex-col flex-1 overflow-hidden outline-none", tabIndex: -1, onKeyDown: handleKeyDown },
112
+ react_1.default.createElement("div", { className: "flex items-center gap-1 px-3 py-1.5 bg-surface-alt border-b border-border text-xs shrink-0 overflow-x-auto" },
113
+ react_1.default.createElement("button", { onClick: () => onPopTo(0), className: "text-brand-accent hover:text-brand-primary hover:underline shrink-0" }, rootLabel),
114
+ columns.map((col, idx) => (react_1.default.createElement(react_1.default.Fragment, { key: col.key },
115
+ react_1.default.createElement("span", { className: "text-muted shrink-0" }, "/"),
116
+ idx < columns.length - 1 ? (react_1.default.createElement("button", { onClick: () => onPopTo(idx + 1), className: "text-brand-accent hover:text-brand-primary hover:underline truncate max-w-[200px] shrink-0" }, col.label)) : (react_1.default.createElement("span", { className: "text-secondary font-medium truncate max-w-[200px] shrink-0" }, col.label)))))),
117
+ react_1.default.createElement("div", { ref: scrollRef, className: "flex flex-1 overflow-x-auto overflow-y-hidden", onMouseDown: handleMouseDown }, columns.map((col) => (react_1.default.createElement("div", { key: col.key, className: "flex flex-col shrink-0 border-r border-border overflow-y-auto", style: { minWidth: minColumnWidth, width: minColumnWidth } }, col.content))))));
118
+ }
119
+ //# sourceMappingURL=CascadeContainer.js.map
@@ -0,0 +1,35 @@
1
+ /**
2
+ * ComparisonView — side-by-side read-only comparison of 2–4 entities.
3
+ * @packageDocumentation
4
+ */
5
+ import React from 'react';
6
+ /**
7
+ * A single column in the comparison view.
8
+ * @public
9
+ */
10
+ export interface IComparisonColumn {
11
+ /** Unique key for React reconciliation */
12
+ readonly key: string;
13
+ /** Column header label */
14
+ readonly label: string;
15
+ /** Column content (typically a detail component) */
16
+ readonly content: React.ReactNode;
17
+ }
18
+ /**
19
+ * Props for the ComparisonView component.
20
+ * @public
21
+ */
22
+ export interface IComparisonViewProps {
23
+ /** Columns to compare (2–4) */
24
+ readonly columns: ReadonlyArray<IComparisonColumn>;
25
+ }
26
+ /**
27
+ * Side-by-side comparison view for entities.
28
+ *
29
+ * Renders 2–4 entity detail views in equal-width columns with
30
+ * synchronized scrolling (future) and column headers.
31
+ *
32
+ * @public
33
+ */
34
+ export declare function ComparisonView(props: IComparisonViewProps): React.ReactElement;
35
+ //# sourceMappingURL=ComparisonView.d.ts.map
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright (c) 2026 Erik Fortune
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ * of this software and associated documentation files (the "Software"), to deal
7
+ * in the Software without restriction, including without limitation the rights
8
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ * copies of the Software, and to permit persons to whom the Software is
10
+ * furnished to do so, subject to the following conditions:
11
+ *
12
+ * The above copyright notice and this permission notice shall be included in all
13
+ * copies or substantial portions of the Software.
14
+ *
15
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ * SOFTWARE.
22
+ */
23
+ var __importDefault = (this && this.__importDefault) || function (mod) {
24
+ return (mod && mod.__esModule) ? mod : { "default": mod };
25
+ };
26
+ Object.defineProperty(exports, "__esModule", { value: true });
27
+ exports.ComparisonView = ComparisonView;
28
+ /**
29
+ * ComparisonView — side-by-side read-only comparison of 2–4 entities.
30
+ * @packageDocumentation
31
+ */
32
+ const react_1 = __importDefault(require("react"));
33
+ // ============================================================================
34
+ // ComparisonView Component
35
+ // ============================================================================
36
+ /**
37
+ * Side-by-side comparison view for entities.
38
+ *
39
+ * Renders 2–4 entity detail views in equal-width columns with
40
+ * synchronized scrolling (future) and column headers.
41
+ *
42
+ * @public
43
+ */
44
+ function ComparisonView(props) {
45
+ const { columns } = props;
46
+ if (columns.length < 2) {
47
+ return (react_1.default.createElement("div", { className: "flex flex-1 items-center justify-center text-muted text-sm" }, "Select at least 2 items to compare."));
48
+ }
49
+ return (react_1.default.createElement("div", { className: "flex flex-1 overflow-hidden" }, columns.map((col) => (react_1.default.createElement("div", { key: col.key, className: "flex flex-col flex-1 min-w-0 border-r border-border last:border-r-0 overflow-hidden" },
50
+ react_1.default.createElement("div", { className: "px-3 py-1.5 bg-surface-alt border-b border-border shrink-0" },
51
+ react_1.default.createElement("span", { className: "text-xs font-medium text-secondary truncate block" }, col.label)),
52
+ react_1.default.createElement("div", { className: "flex-1 overflow-y-auto" }, col.content))))));
53
+ }
54
+ //# sourceMappingURL=ComparisonView.js.map
@@ -0,0 +1,47 @@
1
+ /**
2
+ * EntityTabLayout — shared layout for entity tab content with list + cascade + collapse-on-focus.
3
+ * @packageDocumentation
4
+ */
5
+ import React from 'react';
6
+ import { type ICascadeColumn } from './CascadeContainer';
7
+ import { type IComparisonColumn } from './ComparisonView';
8
+ /**
9
+ * Props for the EntityTabLayout component.
10
+ * @public
11
+ */
12
+ export interface IEntityTabLayoutProps {
13
+ /** The entity list content (rendered in the collapsible left panel) */
14
+ readonly list: React.ReactNode;
15
+ /** Cascade columns to display (empty array = no cascade) */
16
+ readonly cascadeColumns: ReadonlyArray<ICascadeColumn>;
17
+ /** Callback to pop the cascade back to a specific depth (0 = clear all) */
18
+ readonly onPopTo: (depth: number) => void;
19
+ /** Whether the entity list is currently collapsed */
20
+ readonly listCollapsed: boolean;
21
+ /** Callback to collapse the entity list (fired when user clicks inside cascade) */
22
+ readonly onListCollapse: () => void;
23
+ /** Whether compare mode is active */
24
+ readonly compareMode?: boolean;
25
+ /** Columns for the comparison view (when compare mode is active with 2+ selections) */
26
+ readonly comparisonColumns?: ReadonlyArray<IComparisonColumn>;
27
+ /** Whether the comparison view is actively showing (user explicitly triggered) */
28
+ readonly showingComparison?: boolean;
29
+ /** Callback to exit the comparison view (back to selection list) */
30
+ readonly onExitComparison?: () => void;
31
+ /** Columns for variation comparison (when comparing variations of a single recipe) */
32
+ readonly variationCompareColumns?: ReadonlyArray<IComparisonColumn>;
33
+ /** Callback to exit variation comparison mode */
34
+ readonly onExitVariationCompare?: () => void;
35
+ }
36
+ /**
37
+ * Shared layout for entity tab content.
38
+ *
39
+ * Renders an entity list on the left and a cascade container on the right.
40
+ * The list stays expanded while browsing (selecting items in the list).
41
+ * It collapses when the user clicks inside the cascade detail pane,
42
+ * signaling they are focused on the detail rather than browsing.
43
+ *
44
+ * @public
45
+ */
46
+ export declare function EntityTabLayout(props: IEntityTabLayoutProps): React.ReactElement;
47
+ //# sourceMappingURL=EntityTabLayout.d.ts.map
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright (c) 2026 Erik Fortune
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ * of this software and associated documentation files (the "Software"), to deal
7
+ * in the Software without restriction, including without limitation the rights
8
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ * copies of the Software, and to permit persons to whom the Software is
10
+ * furnished to do so, subject to the following conditions:
11
+ *
12
+ * The above copyright notice and this permission notice shall be included in all
13
+ * copies or substantial portions of the Software.
14
+ *
15
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ * SOFTWARE.
22
+ */
23
+ var __importDefault = (this && this.__importDefault) || function (mod) {
24
+ return (mod && mod.__esModule) ? mod : { "default": mod };
25
+ };
26
+ Object.defineProperty(exports, "__esModule", { value: true });
27
+ exports.EntityTabLayout = EntityTabLayout;
28
+ /**
29
+ * EntityTabLayout — shared layout for entity tab content with list + cascade + collapse-on-focus.
30
+ * @packageDocumentation
31
+ */
32
+ const react_1 = __importDefault(require("react"));
33
+ const CascadeContainer_1 = require("./CascadeContainer");
34
+ const responsive_1 = require("../responsive");
35
+ const ComparisonView_1 = require("./ComparisonView");
36
+ // ============================================================================
37
+ // EntityTabLayout Component
38
+ // ============================================================================
39
+ /**
40
+ * Shared layout for entity tab content.
41
+ *
42
+ * Renders an entity list on the left and a cascade container on the right.
43
+ * The list stays expanded while browsing (selecting items in the list).
44
+ * It collapses when the user clicks inside the cascade detail pane,
45
+ * signaling they are focused on the detail rather than browsing.
46
+ *
47
+ * @public
48
+ */
49
+ function EntityTabLayout(props) {
50
+ var _a;
51
+ const { list, cascadeColumns, onPopTo, listCollapsed, onListCollapse, compareMode, comparisonColumns } = props;
52
+ const variationCompareColumns = props.variationCompareColumns;
53
+ const onExitVariationCompare = props.onExitVariationCompare;
54
+ const showingComparison = (_a = props.showingComparison) !== null && _a !== void 0 ? _a : false;
55
+ const onExitComparison = props.onExitComparison;
56
+ const { layoutMode } = (0, responsive_1.useResponsive)();
57
+ const isVariationCompare = variationCompareColumns !== undefined && variationCompareColumns.length >= 2;
58
+ const showComparison = !isVariationCompare &&
59
+ showingComparison &&
60
+ comparisonColumns !== undefined &&
61
+ comparisonColumns.length >= 2;
62
+ const showCascade = !compareMode && !isVariationCompare && !showComparison && cascadeColumns.length > 0;
63
+ const hasCascadeOrCompare = cascadeColumns.length > 0 || showComparison;
64
+ // Variation compare banner — shared between mobile and desktop
65
+ const variationCompareBanner = isVariationCompare && onExitVariationCompare && (react_1.default.createElement("div", { className: "flex items-center gap-2 px-3 py-1.5 bg-status-warning-bg border-b border-status-warning-border shrink-0" },
66
+ react_1.default.createElement("span", { className: "text-xs text-status-warning-text" },
67
+ "Comparing ",
68
+ variationCompareColumns.length,
69
+ " variations"),
70
+ react_1.default.createElement("button", { onClick: onExitVariationCompare, className: "px-2 py-0.5 text-xs rounded border border-status-warning-border text-status-warning-text hover:bg-status-warning-surface transition-colors" }, "Exit")));
71
+ // Mobile: show one pane at a time — list or cascade/comparison full-screen
72
+ if (layoutMode === 'mobile') {
73
+ const hasCascadeContent = showCascade || showComparison || isVariationCompare;
74
+ return (react_1.default.createElement("div", { className: "flex flex-col flex-1 overflow-hidden" },
75
+ variationCompareBanner,
76
+ hasCascadeContent ? (react_1.default.createElement(react_1.default.Fragment, null,
77
+ showCascade && react_1.default.createElement(CascadeContainer_1.CascadeContainer, { columns: cascadeColumns, onPopTo: onPopTo }),
78
+ showComparison && (react_1.default.createElement("div", { className: "flex flex-col flex-1 overflow-hidden" },
79
+ react_1.default.createElement("div", { className: "flex items-center gap-2 px-3 py-1.5 bg-status-info-bg border-b border-status-info-border shrink-0" },
80
+ react_1.default.createElement("span", { className: "text-xs text-status-info-text" },
81
+ "Comparing ",
82
+ comparisonColumns.length,
83
+ " items"),
84
+ onExitComparison && (react_1.default.createElement("button", { onClick: onExitComparison, className: "px-2 py-0.5 text-xs rounded border border-status-info-border text-status-info-text hover:bg-status-info-surface transition-colors" }, "\u2190 Back to list"))),
85
+ react_1.default.createElement(ComparisonView_1.ComparisonView, { columns: comparisonColumns }))),
86
+ isVariationCompare && react_1.default.createElement(ComparisonView_1.ComparisonView, { columns: variationCompareColumns }))) : (react_1.default.createElement("div", { className: "flex flex-col flex-1 overflow-hidden" }, list))));
87
+ }
88
+ // Desktop/compact: side-by-side list and cascade
89
+ return (react_1.default.createElement("div", { className: "flex flex-col flex-1 overflow-hidden" },
90
+ variationCompareBanner,
91
+ react_1.default.createElement("div", { className: "flex flex-1 overflow-hidden" },
92
+ react_1.default.createElement("div", { className: `flex flex-col overflow-hidden transition-all ${isVariationCompare || showComparison
93
+ ? 'w-0 min-w-0'
94
+ : listCollapsed
95
+ ? 'w-0 min-w-0'
96
+ : hasCascadeOrCompare
97
+ ? 'w-1/4 max-w-xs shrink-0 border-r border-border'
98
+ : 'w-full max-w-sm shrink-0 border-r border-border'}` }, list),
99
+ showCascade && (react_1.default.createElement(CascadeContainer_1.CascadeContainer, { columns: cascadeColumns, onPopTo: onPopTo, onFocus: onListCollapse })),
100
+ showComparison && (react_1.default.createElement("div", { className: "flex flex-col flex-1 overflow-hidden" },
101
+ react_1.default.createElement("div", { className: "flex items-center gap-2 px-3 py-1.5 bg-status-info-bg border-b border-status-info-border shrink-0" },
102
+ react_1.default.createElement("span", { className: "text-xs text-status-info-text" },
103
+ "Comparing ",
104
+ comparisonColumns.length,
105
+ " items"),
106
+ onExitComparison && (react_1.default.createElement("button", { onClick: onExitComparison, className: "px-2 py-0.5 text-xs rounded border border-status-info-border text-status-info-text hover:bg-status-info-surface transition-colors" }, "\u2190 Back to list"))),
107
+ react_1.default.createElement(ComparisonView_1.ComparisonView, { columns: comparisonColumns }))),
108
+ isVariationCompare && react_1.default.createElement(ComparisonView_1.ComparisonView, { columns: variationCompareColumns }))));
109
+ }
110
+ //# sourceMappingURL=EntityTabLayout.js.map
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Mobile view-stack cascade — one full-screen column at a time with back navigation.
3
+ * @packageDocumentation
4
+ */
5
+ import React from 'react';
6
+ import { type ICascadeContainerProps } from './CascadeContainer';
7
+ /**
8
+ * Mobile replacement for {@link CascadeContainer}.
9
+ *
10
+ * Shows the rightmost (deepest) cascade column full-screen with a back button
11
+ * that pops one level at a time. At the first column, back returns to the list
12
+ * by calling `onPopTo(0)`.
13
+ *
14
+ * Accepts the same props as {@link CascadeContainer} so `CascadeContainer` can
15
+ * delegate to it transparently on mobile.
16
+ *
17
+ * @public
18
+ */
19
+ export declare function MobileCascadeStack(props: ICascadeContainerProps): React.ReactElement | null;
20
+ //# sourceMappingURL=MobileCascadeStack.d.ts.map
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright (c) 2026 Erik Fortune
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ * of this software and associated documentation files (the "Software"), to deal
7
+ * in the Software without restriction, including without limitation the rights
8
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ * copies of the Software, and to permit persons to whom the Software is
10
+ * furnished to do so, subject to the following conditions:
11
+ *
12
+ * The above copyright notice and this permission notice shall be included in all
13
+ * copies or substantial portions of the Software.
14
+ *
15
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ * SOFTWARE.
22
+ */
23
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
24
+ if (k2 === undefined) k2 = k;
25
+ var desc = Object.getOwnPropertyDescriptor(m, k);
26
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
27
+ desc = { enumerable: true, get: function() { return m[k]; } };
28
+ }
29
+ Object.defineProperty(o, k2, desc);
30
+ }) : (function(o, m, k, k2) {
31
+ if (k2 === undefined) k2 = k;
32
+ o[k2] = m[k];
33
+ }));
34
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
35
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
36
+ }) : function(o, v) {
37
+ o["default"] = v;
38
+ });
39
+ var __importStar = (this && this.__importStar) || (function () {
40
+ var ownKeys = function(o) {
41
+ ownKeys = Object.getOwnPropertyNames || function (o) {
42
+ var ar = [];
43
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
44
+ return ar;
45
+ };
46
+ return ownKeys(o);
47
+ };
48
+ return function (mod) {
49
+ if (mod && mod.__esModule) return mod;
50
+ var result = {};
51
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
52
+ __setModuleDefault(result, mod);
53
+ return result;
54
+ };
55
+ })();
56
+ Object.defineProperty(exports, "__esModule", { value: true });
57
+ exports.MobileCascadeStack = MobileCascadeStack;
58
+ /**
59
+ * Mobile view-stack cascade — one full-screen column at a time with back navigation.
60
+ * @packageDocumentation
61
+ */
62
+ const react_1 = __importStar(require("react"));
63
+ /**
64
+ * Mobile replacement for {@link CascadeContainer}.
65
+ *
66
+ * Shows the rightmost (deepest) cascade column full-screen with a back button
67
+ * that pops one level at a time. At the first column, back returns to the list
68
+ * by calling `onPopTo(0)`.
69
+ *
70
+ * Accepts the same props as {@link CascadeContainer} so `CascadeContainer` can
71
+ * delegate to it transparently on mobile.
72
+ *
73
+ * @public
74
+ */
75
+ function MobileCascadeStack(props) {
76
+ const { columns, onPopTo, rootLabel = 'List' } = props;
77
+ const handleBack = (0, react_1.useCallback)(() => {
78
+ if (columns.length > 1) {
79
+ onPopTo(columns.length - 1);
80
+ }
81
+ else {
82
+ onPopTo(0);
83
+ }
84
+ }, [columns.length, onPopTo]);
85
+ if (columns.length === 0) {
86
+ return null;
87
+ }
88
+ const currentColumn = columns[columns.length - 1];
89
+ const backLabel = columns.length > 1 ? columns[columns.length - 2].label : rootLabel;
90
+ return (react_1.default.createElement("div", { className: "flex flex-col flex-1 overflow-hidden" },
91
+ react_1.default.createElement("div", { className: "flex items-center gap-2 px-3 py-2 bg-surface-alt border-b border-border shrink-0" },
92
+ react_1.default.createElement("button", { onClick: handleBack, className: "flex items-center gap-1 text-sm text-brand-accent hover:text-brand-primary", "aria-label": `Back to ${backLabel}` },
93
+ react_1.default.createElement("svg", { className: "w-4 h-4 shrink-0", fill: "none", viewBox: "0 0 24 24", strokeWidth: 2, stroke: "currentColor" },
94
+ react_1.default.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M15.75 19.5L8.25 12l7.5-7.5" })),
95
+ backLabel),
96
+ columns.length > 1 && (react_1.default.createElement("span", { className: "ml-auto text-xs text-muted truncate" }, currentColumn.label))),
97
+ react_1.default.createElement("div", { className: "flex flex-col flex-1 overflow-y-auto" }, currentColumn.content)));
98
+ }
99
+ //# sourceMappingURL=MobileCascadeStack.js.map
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Cascade packlet - column cascade container, layout, and semantic operations.
3
+ * @packageDocumentation
4
+ */
5
+ export { CascadeContainer, type ICascadeContainerProps, type ICascadeColumn } from './CascadeContainer';
6
+ export { MobileCascadeStack } from './MobileCascadeStack';
7
+ export { EntityTabLayout, type IEntityTabLayoutProps } from './EntityTabLayout';
8
+ export { ComparisonView, type IComparisonViewProps, type IComparisonColumn } from './ComparisonView';
9
+ export { type CascadeColumnMode, type CascadeEntryOrigin, type ICascadeEntryBase, CASCADE_NEW_ENTITY_ID } from './model';
10
+ export { useSquashAt, useCascadeDrillDown } from './useCascadeTransitions';
11
+ export { type ICascadeConflict, type ICascadeFind, type CascadeEntrySpec, type ICascadeOps, useCascadeOps } from './useCascadeOps';
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright (c) 2026 Erik Fortune
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ * of this software and associated documentation files (the "Software"), to deal
7
+ * in the Software without restriction, including without limitation the rights
8
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ * copies of the Software, and to permit persons to whom the Software is
10
+ * furnished to do so, subject to the following conditions:
11
+ *
12
+ * The above copyright notice and this permission notice shall be included in all
13
+ * copies or substantial portions of the Software.
14
+ *
15
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ * SOFTWARE.
22
+ */
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ exports.useCascadeOps = exports.useCascadeDrillDown = exports.useSquashAt = exports.CASCADE_NEW_ENTITY_ID = exports.ComparisonView = exports.EntityTabLayout = exports.MobileCascadeStack = exports.CascadeContainer = void 0;
25
+ /**
26
+ * Cascade packlet - column cascade container, layout, and semantic operations.
27
+ * @packageDocumentation
28
+ */
29
+ // UI components
30
+ var CascadeContainer_1 = require("./CascadeContainer");
31
+ Object.defineProperty(exports, "CascadeContainer", { enumerable: true, get: function () { return CascadeContainer_1.CascadeContainer; } });
32
+ var MobileCascadeStack_1 = require("./MobileCascadeStack");
33
+ Object.defineProperty(exports, "MobileCascadeStack", { enumerable: true, get: function () { return MobileCascadeStack_1.MobileCascadeStack; } });
34
+ var EntityTabLayout_1 = require("./EntityTabLayout");
35
+ Object.defineProperty(exports, "EntityTabLayout", { enumerable: true, get: function () { return EntityTabLayout_1.EntityTabLayout; } });
36
+ var ComparisonView_1 = require("./ComparisonView");
37
+ Object.defineProperty(exports, "ComparisonView", { enumerable: true, get: function () { return ComparisonView_1.ComparisonView; } });
38
+ // Cascade model types
39
+ var model_1 = require("./model");
40
+ Object.defineProperty(exports, "CASCADE_NEW_ENTITY_ID", { enumerable: true, get: function () { return model_1.CASCADE_NEW_ENTITY_ID; } });
41
+ // Cascade transition hooks
42
+ var useCascadeTransitions_1 = require("./useCascadeTransitions");
43
+ Object.defineProperty(exports, "useSquashAt", { enumerable: true, get: function () { return useCascadeTransitions_1.useSquashAt; } });
44
+ Object.defineProperty(exports, "useCascadeDrillDown", { enumerable: true, get: function () { return useCascadeTransitions_1.useCascadeDrillDown; } });
45
+ // Semantic cascade operations
46
+ var useCascadeOps_1 = require("./useCascadeOps");
47
+ Object.defineProperty(exports, "useCascadeOps", { enumerable: true, get: function () { return useCascadeOps_1.useCascadeOps; } });
48
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Base cascade model types for column cascade navigation.
3
+ *
4
+ * These types are domain-agnostic — they define the structure and semantics
5
+ * of cascade navigation without knowledge of specific entity types.
6
+ * Domain-specific applications extend {@link ICascadeEntryBase} with their
7
+ * own entity types and additional fields.
8
+ *
9
+ * @packageDocumentation
10
+ */
11
+ /**
12
+ * Mode for a cascade column (view-only, editing, or creating a new entity).
13
+ * @public
14
+ */
15
+ export type CascadeColumnMode = 'view' | 'edit' | 'create' | 'preview';
16
+ /**
17
+ * How a cascade entry was opened — determines save/cancel behavior.
18
+ *
19
+ * - `'primary'` — selected from the entity list. Save/cancel transitions to view mode in-place.
20
+ * - `'nested'` — reached via drill-down, typeahead-create, or sub-entity editing. Save/cancel pops (removes entry).
21
+ *
22
+ * Entries without an explicit origin are treated as `'primary'` for backwards compatibility.
23
+ * @public
24
+ */
25
+ export type CascadeEntryOrigin = 'primary' | 'nested';
26
+ /**
27
+ * Sentinel value used as entityId when creating a new entity.
28
+ * @public
29
+ */
30
+ export declare const CASCADE_NEW_ENTITY_ID: '__new__';
31
+ /**
32
+ * Base interface for a single entry in the column cascade stack.
33
+ *
34
+ * This interface contains only the fields needed by the generic cascade
35
+ * operations ({@link useCascadeOps}, {@link useSquashAt}, {@link useCascadeDrillDown}).
36
+ * Domain-specific applications should extend this interface with additional
37
+ * fields (e.g., target weights, source references, session context).
38
+ *
39
+ * @public
40
+ */
41
+ export interface ICascadeEntryBase {
42
+ /** The type of entity displayed in this column (domain-specific string). */
43
+ readonly entityType: string;
44
+ /** The ID of the entity (qualified ID, e.g. 'collection.base-id'). */
45
+ readonly entityId: string;
46
+ /** Whether the column is in view, edit, create, or preview mode. */
47
+ readonly mode: CascadeColumnMode;
48
+ /** How this entry was opened. Determines save/cancel behavior. @see CascadeEntryOrigin */
49
+ readonly origin?: CascadeEntryOrigin;
50
+ /** Optional pre-resolved materialized entity. */
51
+ readonly entity?: unknown;
52
+ /** Whether this cascade entry has unsaved changes (set by the owning tab component). */
53
+ readonly hasChanges?: boolean;
54
+ /** Pre-fill name for entity creation (set when on-blur typeahead doesn't match). */
55
+ readonly prefillName?: string;
56
+ }
57
+ //# sourceMappingURL=model.d.ts.map
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright (c) 2026 Erik Fortune
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ * of this software and associated documentation files (the "Software"), to deal
7
+ * in the Software without restriction, including without limitation the rights
8
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ * copies of the Software, and to permit persons to whom the Software is
10
+ * furnished to do so, subject to the following conditions:
11
+ *
12
+ * The above copyright notice and this permission notice shall be included in all
13
+ * copies or substantial portions of the Software.
14
+ *
15
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ * SOFTWARE.
22
+ */
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ exports.CASCADE_NEW_ENTITY_ID = void 0;
25
+ // ============================================================================
26
+ // Cascade Entry Base
27
+ // ============================================================================
28
+ /**
29
+ * Sentinel value used as entityId when creating a new entity.
30
+ * @public
31
+ */
32
+ exports.CASCADE_NEW_ENTITY_ID = '__new__';
33
+ //# sourceMappingURL=model.js.map