@happyvertical/smrt-svelte 0.55.9 → 0.55.11

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 (119) hide show
  1. package/AGENTS.md +2 -1
  2. package/agents/cookbook-shell.md +176 -0
  3. package/agents/overview-presentation.md +8 -0
  4. package/agents/overview-surfaces.md +133 -17
  5. package/agents/screens.md +5 -0
  6. package/agents/workspace.md +6 -0
  7. package/dist/components/activity/ActivityList.svelte +35 -0
  8. package/dist/components/activity/ActivityList.svelte.d.ts +11 -0
  9. package/dist/components/activity/ActivityList.svelte.d.ts.map +1 -0
  10. package/dist/components/activity/index.d.ts +3 -0
  11. package/dist/components/activity/index.d.ts.map +1 -0
  12. package/dist/components/activity/index.js +1 -0
  13. package/dist/components/activity/safe-href.d.ts +3 -0
  14. package/dist/components/activity/safe-href.d.ts.map +1 -0
  15. package/dist/components/activity/safe-href.js +12 -0
  16. package/dist/components/activity/types.d.ts +9 -0
  17. package/dist/components/activity/types.d.ts.map +1 -0
  18. package/dist/components/activity/types.js +1 -0
  19. package/dist/components/cookbook/CookbookApp.svelte +236 -0
  20. package/dist/components/cookbook/CookbookApp.svelte.d.ts +5 -0
  21. package/dist/components/cookbook/CookbookApp.svelte.d.ts.map +1 -0
  22. package/dist/components/cookbook/CookbookSectionOverview.svelte +71 -0
  23. package/dist/components/cookbook/CookbookSectionOverview.svelte.d.ts +20 -0
  24. package/dist/components/cookbook/CookbookSectionOverview.svelte.d.ts.map +1 -0
  25. package/dist/components/cookbook/CookbookSectionPage.svelte +133 -0
  26. package/dist/components/cookbook/CookbookSectionPage.svelte.d.ts +5 -0
  27. package/dist/components/cookbook/CookbookSectionPage.svelte.d.ts.map +1 -0
  28. package/dist/components/cookbook/brand-theme.d.ts +11 -0
  29. package/dist/components/cookbook/brand-theme.d.ts.map +1 -0
  30. package/dist/components/cookbook/brand-theme.js +24 -0
  31. package/dist/components/cookbook/build.d.ts +8 -0
  32. package/dist/components/cookbook/build.d.ts.map +1 -0
  33. package/dist/components/cookbook/build.js +277 -0
  34. package/dist/components/cookbook/catalog.d.ts +37 -0
  35. package/dist/components/cookbook/catalog.d.ts.map +1 -0
  36. package/dist/components/cookbook/catalog.js +99 -0
  37. package/dist/components/cookbook/context.d.ts +23 -0
  38. package/dist/components/cookbook/context.d.ts.map +1 -0
  39. package/dist/components/cookbook/context.js +15 -0
  40. package/dist/components/cookbook/index.d.ts +22 -0
  41. package/dist/components/cookbook/index.d.ts.map +1 -0
  42. package/dist/components/cookbook/index.js +20 -0
  43. package/dist/components/cookbook/page.d.ts +23 -0
  44. package/dist/components/cookbook/page.d.ts.map +1 -0
  45. package/dist/components/cookbook/page.js +32 -0
  46. package/dist/components/cookbook/registry.d.ts +37 -0
  47. package/dist/components/cookbook/registry.d.ts.map +1 -0
  48. package/dist/components/cookbook/registry.js +38 -0
  49. package/dist/components/cookbook/sections.d.ts +60 -0
  50. package/dist/components/cookbook/sections.d.ts.map +1 -0
  51. package/dist/components/cookbook/sections.js +88 -0
  52. package/dist/components/cookbook/server.d.ts +61 -0
  53. package/dist/components/cookbook/server.d.ts.map +1 -0
  54. package/dist/components/cookbook/server.js +108 -0
  55. package/dist/components/cookbook/theme.d.ts +21 -0
  56. package/dist/components/cookbook/theme.d.ts.map +1 -0
  57. package/dist/components/cookbook/theme.js +53 -0
  58. package/dist/components/cookbook/types.d.ts +204 -0
  59. package/dist/components/cookbook/types.d.ts.map +1 -0
  60. package/dist/components/cookbook/types.js +1 -0
  61. package/dist/components/notifications/LocalizedNotifications.fixture.svelte +16 -0
  62. package/dist/components/notifications/LocalizedNotifications.fixture.svelte.d.ts +11 -0
  63. package/dist/components/notifications/LocalizedNotifications.fixture.svelte.d.ts.map +1 -0
  64. package/dist/components/notifications/NotificationBell.svelte +136 -0
  65. package/dist/components/notifications/NotificationBell.svelte.d.ts +13 -0
  66. package/dist/components/notifications/NotificationBell.svelte.d.ts.map +1 -0
  67. package/dist/components/notifications/index.d.ts +3 -0
  68. package/dist/components/notifications/index.d.ts.map +1 -0
  69. package/dist/components/notifications/index.js +1 -0
  70. package/dist/components/notifications/types.d.ts +27 -0
  71. package/dist/components/notifications/types.d.ts.map +1 -0
  72. package/dist/components/notifications/types.js +1 -0
  73. package/dist/components/overview/OverviewAssistantUndo.svelte +77 -0
  74. package/dist/components/overview/OverviewAssistantUndo.svelte.d.ts +13 -0
  75. package/dist/components/overview/OverviewAssistantUndo.svelte.d.ts.map +1 -0
  76. package/dist/components/overview/OverviewGrid.svelte +5 -2
  77. package/dist/components/overview/OverviewGrid.svelte.d.ts.map +1 -1
  78. package/dist/components/overview/assistant-surface.d.ts +90 -0
  79. package/dist/components/overview/assistant-surface.d.ts.map +1 -0
  80. package/dist/components/overview/assistant-surface.js +65 -0
  81. package/dist/components/overview/assistant.svelte.d.ts +115 -0
  82. package/dist/components/overview/assistant.svelte.d.ts.map +1 -0
  83. package/dist/components/overview/assistant.svelte.js +260 -0
  84. package/dist/components/overview/controller.svelte.d.ts +8 -0
  85. package/dist/components/overview/controller.svelte.d.ts.map +1 -1
  86. package/dist/components/overview/controller.svelte.js +76 -13
  87. package/dist/components/overview/grid-types.d.ts +6 -2
  88. package/dist/components/overview/grid-types.d.ts.map +1 -1
  89. package/dist/components/overview/index.d.ts +2 -0
  90. package/dist/components/overview/index.d.ts.map +1 -1
  91. package/dist/components/overview/index.js +2 -0
  92. package/dist/components/overview/operations.d.ts +169 -0
  93. package/dist/components/overview/operations.d.ts.map +1 -0
  94. package/dist/components/overview/operations.js +358 -0
  95. package/dist/components/overview/server.d.ts +2 -0
  96. package/dist/components/overview/server.d.ts.map +1 -1
  97. package/dist/components/overview/server.js +2 -0
  98. package/dist/components/workspace/admin-shell/settings-delta.d.ts +21 -0
  99. package/dist/components/workspace/admin-shell/settings-delta.d.ts.map +1 -0
  100. package/dist/components/workspace/admin-shell/settings-delta.js +142 -0
  101. package/dist/components/workspace/index.d.ts +1 -0
  102. package/dist/components/workspace/index.d.ts.map +1 -1
  103. package/dist/components/workspace/index.js +1 -0
  104. package/dist/components/workspace/server/index.d.ts +6 -2
  105. package/dist/components/workspace/server/index.d.ts.map +1 -1
  106. package/dist/components/workspace/server/index.js +5 -2
  107. package/dist/i18n/server.d.ts +1 -0
  108. package/dist/i18n/server.d.ts.map +1 -1
  109. package/dist/i18n/server.js +1 -0
  110. package/dist/i18n/strings.notifications.d.ts +12 -0
  111. package/dist/i18n/strings.notifications.d.ts.map +1 -0
  112. package/dist/i18n/strings.notifications.js +13 -0
  113. package/dist/i18n/strings.overview.d.ts +9 -0
  114. package/dist/i18n/strings.overview.d.ts.map +1 -1
  115. package/dist/i18n/strings.overview.js +11 -0
  116. package/dist/index.d.ts +2 -0
  117. package/dist/index.d.ts.map +1 -1
  118. package/dist/index.js +2 -0
  119. package/package.json +31 -14
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Navigation sections and entry ids (#3749), ported from smrt-planner's
3
+ * `recipes/sections.ts` so a generated app and the planner derive the same
4
+ * ids: a saved layout names them, so they must stay stable.
5
+ */
6
+ import type { RecipeSection } from '@happyvertical/smrt-types';
7
+ import type { CookbookRecipe } from './types.js';
8
+ /** The section that holds feature models no recipe covers. */
9
+ export declare const FEATURE_SECTION: RecipeSection;
10
+ /** Icon of an entry whose recipe names none, and of feature entries. */
11
+ export declare const DEFAULT_ENTRY_ICON = "fileText";
12
+ /** The icon of a section the user made, or one the host knows nothing of. */
13
+ export declare const DEFAULT_SECTION_ICON = "folder";
14
+ /** The id of the group (or recipe) a recipe belongs to. */
15
+ export declare function groupId(recipe: Pick<CookbookRecipe, 'id' | 'group'>): string;
16
+ /**
17
+ * The nav section a recipe's entries sit under by default: the section it
18
+ * suggests, else its group, else the recipe itself.
19
+ */
20
+ export declare function navSectionOf(recipe: CookbookRecipe): RecipeSection;
21
+ export type NavSectionGroup = RecipeSection & {
22
+ recipes: CookbookRecipe[];
23
+ };
24
+ /** Nav sections of the given recipes, in the order their first recipe comes. */
25
+ export declare function buildNavSections(recipes: readonly CookbookRecipe[]): NavSectionGroup[];
26
+ /**
27
+ * The stable layout id of a navigation item: `item:<package>:<Model>`, or
28
+ * `item:<package>:<Model>:<key>` when a model appears twice in the nav and the
29
+ * extra entry declares a fixed `key`. It never names the section, the label or
30
+ * the href, so renaming an entry or moving a recipe's section leaves a saved
31
+ * layout valid.
32
+ */
33
+ export declare function navItemId(packageId: string, modelName: string, key?: string): string;
34
+ /** `section:<id>` for a recipe-suggested section. */
35
+ export declare function sectionLayoutId(id: string): string;
36
+ /**
37
+ * A section page lives at `/s/<slug>/`. The slug is the layout id with its
38
+ * `kind:` prefix turned into `kind-` (`section:sales` -> `section-sales`), so
39
+ * no path segment holds a colon. Only the first colon is the prefix.
40
+ */
41
+ export declare function sectionSlug(id: string): string;
42
+ /** The layout id a slug names; the inverse of {@link sectionSlug}. */
43
+ export declare function sectionIdFromSlug(slug: string): string;
44
+ /** Default in-app path of a section page. */
45
+ export declare function defaultSectionPath(id: string): string;
46
+ /** Default in-app path of a model entry: `/m/<pkg>/<Model>/[<key>/]`. */
47
+ export declare function defaultEntryPath(entry: {
48
+ packageId: string;
49
+ modelName: string;
50
+ key?: string;
51
+ }): string;
52
+ /**
53
+ * The line under an entry on its section card: the recipe's own text first,
54
+ * then the model's description, then a plain fallback.
55
+ */
56
+ export declare function entryDescription(own: string | undefined, model: {
57
+ description?: string;
58
+ name: string;
59
+ }): string;
60
+ //# sourceMappingURL=sections.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sections.d.ts","sourceRoot":"","sources":["../../../src/components/cookbook/sections.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,8DAA8D;AAC9D,eAAO,MAAM,eAAe,EAAE,aAK7B,CAAC;AAEF,wEAAwE;AACxE,eAAO,MAAM,kBAAkB,aAAa,CAAC;AAE7C,6EAA6E;AAC7E,eAAO,MAAM,oBAAoB,WAAW,CAAC;AAE7C,2DAA2D;AAC3D,wBAAgB,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,IAAI,GAAG,OAAO,CAAC,GAAG,MAAM,CAE5E;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,cAAc,GAAG,aAAa,CAOlE;AAED,MAAM,MAAM,eAAe,GAAG,aAAa,GAAG;IAAE,OAAO,EAAE,cAAc,EAAE,CAAA;CAAE,CAAC;AAE5E,gFAAgF;AAChF,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,SAAS,cAAc,EAAE,GACjC,eAAe,EAAE,CAanB;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CACvB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,GAAG,CAAC,EAAE,MAAM,GACX,MAAM,CAER;AAED,qDAAqD;AACrD,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAElD;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED,sEAAsE;AACtE,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,6CAA6C;AAC7C,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,yEAAyE;AACzE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,GAAG,MAAM,CAET;AAMD;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,KAAK,EAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC5C,MAAM,CAMR"}
@@ -0,0 +1,88 @@
1
+ /** The section that holds feature models no recipe covers. */
2
+ export const FEATURE_SECTION = {
3
+ id: 'more',
4
+ label: 'More',
5
+ icon: 'layers',
6
+ description: 'Extra records you added one at a time.',
7
+ };
8
+ /** Icon of an entry whose recipe names none, and of feature entries. */
9
+ export const DEFAULT_ENTRY_ICON = 'fileText';
10
+ /** The icon of a section the user made, or one the host knows nothing of. */
11
+ export const DEFAULT_SECTION_ICON = 'folder';
12
+ /** The id of the group (or recipe) a recipe belongs to. */
13
+ export function groupId(recipe) {
14
+ return recipe.group?.id ?? recipe.id;
15
+ }
16
+ /**
17
+ * The nav section a recipe's entries sit under by default: the section it
18
+ * suggests, else its group, else the recipe itself.
19
+ */
20
+ export function navSectionOf(recipe) {
21
+ return (recipe.section ?? {
22
+ id: groupId(recipe),
23
+ label: recipe.group?.label ?? recipe.label,
24
+ });
25
+ }
26
+ /** Nav sections of the given recipes, in the order their first recipe comes. */
27
+ export function buildNavSections(recipes) {
28
+ const out = new Map();
29
+ for (const recipe of recipes) {
30
+ const nav = navSectionOf(recipe);
31
+ const existing = out.get(nav.id);
32
+ if (existing) {
33
+ existing.recipes.push(recipe);
34
+ // The first recipe supplies the label; a later one may add what is missing.
35
+ existing.icon ??= nav.icon;
36
+ existing.description ??= nav.description;
37
+ }
38
+ else
39
+ out.set(nav.id, { ...nav, recipes: [recipe] });
40
+ }
41
+ return [...out.values()];
42
+ }
43
+ /**
44
+ * The stable layout id of a navigation item: `item:<package>:<Model>`, or
45
+ * `item:<package>:<Model>:<key>` when a model appears twice in the nav and the
46
+ * extra entry declares a fixed `key`. It never names the section, the label or
47
+ * the href, so renaming an entry or moving a recipe's section leaves a saved
48
+ * layout valid.
49
+ */
50
+ export function navItemId(packageId, modelName, key) {
51
+ return `item:${packageId}:${modelName}${key ? `:${key}` : ''}`;
52
+ }
53
+ /** `section:<id>` for a recipe-suggested section. */
54
+ export function sectionLayoutId(id) {
55
+ return `section:${id}`;
56
+ }
57
+ /**
58
+ * A section page lives at `/s/<slug>/`. The slug is the layout id with its
59
+ * `kind:` prefix turned into `kind-` (`section:sales` -> `section-sales`), so
60
+ * no path segment holds a colon. Only the first colon is the prefix.
61
+ */
62
+ export function sectionSlug(id) {
63
+ return id.replace(':', '-');
64
+ }
65
+ /** The layout id a slug names; the inverse of {@link sectionSlug}. */
66
+ export function sectionIdFromSlug(slug) {
67
+ return slug.replace('-', ':');
68
+ }
69
+ /** Default in-app path of a section page. */
70
+ export function defaultSectionPath(id) {
71
+ return `/s/${sectionSlug(id)}/`;
72
+ }
73
+ /** Default in-app path of a model entry: `/m/<pkg>/<Model>/[<key>/]`. */
74
+ export function defaultEntryPath(entry) {
75
+ return `/m/${entry.packageId}/${entry.modelName}/${entry.key ? `${entry.key}/` : ''}`;
76
+ }
77
+ function humanizeName(name) {
78
+ return name.replace(/([a-z0-9])([A-Z])/g, '$1 $2').toLowerCase();
79
+ }
80
+ /**
81
+ * The line under an entry on its section card: the recipe's own text first,
82
+ * then the model's description, then a plain fallback.
83
+ */
84
+ export function entryDescription(own, model) {
85
+ return (own?.trim() ||
86
+ model.description?.trim() ||
87
+ `Your ${humanizeName(model.name)} records, all in one place.`);
88
+ }
@@ -0,0 +1,61 @@
1
+ import type { Cookbook } from '@happyvertical/smrt-types';
2
+ import { type CookbookManifest } from './catalog.js';
3
+ import type { CookbookCatalog } from './types.js';
4
+ export { buildCookbookShell } from './build.js';
5
+ export { type CookbookManifest, catalogFromManifests, narrowCatalog, packageIdOf, } from './catalog.js';
6
+ export { resolveCookbookTheme } from './theme.js';
7
+ export type * from './types.js';
8
+ export declare const COOKBOOK_FILE = "smrt.cookbook.json";
9
+ /** The result of validating a cookbook document (`validateCookbook` in smrt-core). */
10
+ export type CookbookValidation = {
11
+ ok: true;
12
+ cookbook: Cookbook;
13
+ warnings?: string[];
14
+ } | {
15
+ ok: false;
16
+ errors: string[];
17
+ };
18
+ export type CookbookValidator = (document: unknown, options?: {
19
+ recipes?: Iterable<string>;
20
+ }) => CookbookValidation;
21
+ /** What `+layout.server.ts` returns and `CookbookApp` takes. Plain JSON. */
22
+ export interface CookbookAppData {
23
+ cookbook: Cookbook;
24
+ /** Only the recipes and models the cookbook uses. */
25
+ catalog: CookbookCatalog;
26
+ /** The validator's warnings. */
27
+ warnings: string[];
28
+ }
29
+ export interface LoadCookbookAppOptions {
30
+ /** Project root; default `process.cwd()`. */
31
+ root?: string;
32
+ /** Cookbook file relative to `root`; default {@link COOKBOOK_FILE}. */
33
+ file?: string;
34
+ /**
35
+ * Packages whose `manifest.json` to read. Default: every dependency of the
36
+ * project's `package.json` that exports `./manifest.json`.
37
+ */
38
+ packages?: readonly string[];
39
+ /**
40
+ * The validator. Default: `validateCookbook` from
41
+ * `@happyvertical/smrt-core/cookbook`, which the app depends on.
42
+ */
43
+ validate?: CookbookValidator;
44
+ }
45
+ /**
46
+ * Read a package's `manifest.json` through its `./manifest.json` (or
47
+ * `./manifest`) export; `null` when the package has none or is not installed.
48
+ */
49
+ export declare function readInstalledManifest(root: string, packageName: string): Promise<CookbookManifest | null>;
50
+ /** Read the manifests of `packages`, skipping those that have none. */
51
+ export declare function readInstalledManifests(root: string, packages?: readonly string[]): Promise<CookbookManifest[]>;
52
+ /**
53
+ * Load and validate the project's cookbook and resolve it against the
54
+ * installed packages' recipes. Throws when the cookbook is missing or invalid
55
+ * (the message lists every problem), including a recipe no installed package
56
+ * declares.
57
+ */
58
+ export declare function loadCookbookApp(options?: LoadCookbookAppOptions): Promise<CookbookAppData>;
59
+ /** Whether `root` has a cookbook file (for apps that fall back to a plain shell). */
60
+ export declare function hasCookbook(root?: string, file?: string): Promise<boolean>;
61
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/components/cookbook/server.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EACL,KAAK,gBAAgB,EAGtB,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EACL,KAAK,gBAAgB,EACrB,oBAAoB,EACpB,aAAa,EACb,WAAW,GACZ,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAClD,mBAAmB,YAAY,CAAC;AAEhC,eAAO,MAAM,aAAa,uBAAuB,CAAC;AAElD,sFAAsF;AACtF,MAAM,MAAM,kBAAkB,GAC1B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,GACrD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAEpC,MAAM,MAAM,iBAAiB,GAAG,CAC9B,QAAQ,EAAE,OAAO,EACjB,OAAO,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAA;CAAE,KACrC,kBAAkB,CAAC;AAExB,4EAA4E;AAC5E,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,QAAQ,CAAC;IACnB,qDAAqD;IACrD,OAAO,EAAE,eAAe,CAAC;IACzB,gCAAgC;IAChC,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,sBAAsB;IACrC,6CAA6C;IAC7C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B;;;OAGG;IACH,QAAQ,CAAC,EAAE,iBAAiB,CAAC;CAC9B;AA8BD;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAclC;AAED,uEAAuE;AACvE,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,MAAM,EACZ,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,GAC3B,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAM7B;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,eAAe,CAAC,CAgC1B;AAED,qFAAqF;AACrF,wBAAsB,WAAW,CAC/B,IAAI,GAAE,MAAsB,EAC5B,IAAI,GAAE,MAAsB,GAC3B,OAAO,CAAC,OAAO,CAAC,CAOlB"}
@@ -0,0 +1,108 @@
1
+ /**
2
+ * @happyvertical/smrt-svelte/cookbook/server
3
+ *
4
+ * Node-only loading for a cookbook app's `+layout.server.ts` (#3749): read and
5
+ * validate `smrt.cookbook.json`, read the installed packages' manifests and
6
+ * return the plain-JSON data `CookbookApp` takes. Also re-exports the pure,
7
+ * Svelte-free builder so a server can derive the shell without a DOM.
8
+ */
9
+ import { access, readFile } from 'node:fs/promises';
10
+ import { createRequire } from 'node:module';
11
+ import { join, resolve } from 'node:path';
12
+ import { catalogFromManifests, narrowCatalog, } from './catalog.js';
13
+ export { buildCookbookShell } from './build.js';
14
+ export { catalogFromManifests, narrowCatalog, packageIdOf, } from './catalog.js';
15
+ export { resolveCookbookTheme } from './theme.js';
16
+ export const COOKBOOK_FILE = 'smrt.cookbook.json';
17
+ async function readJson(path) {
18
+ return JSON.parse(await readFile(path, 'utf8'));
19
+ }
20
+ async function defaultValidator() {
21
+ try {
22
+ const mod = (await import(
23
+ /* @vite-ignore */ '@happyvertical/smrt-core/cookbook'));
24
+ return mod.validateCookbook;
25
+ }
26
+ catch (error) {
27
+ throw new Error('loadCookbookApp needs @happyvertical/smrt-core (it validates the ' +
28
+ 'cookbook); install it or pass `validate`. ' +
29
+ (error instanceof Error ? error.message : String(error)));
30
+ }
31
+ }
32
+ /** Dependencies of the project that publish a manifest. */
33
+ async function manifestPackages(root) {
34
+ const pkg = (await readJson(join(root, 'package.json')));
35
+ return Object.keys({ ...pkg.dependencies, ...pkg.devDependencies }).sort();
36
+ }
37
+ /**
38
+ * Read a package's `manifest.json` through its `./manifest.json` (or
39
+ * `./manifest`) export; `null` when the package has none or is not installed.
40
+ */
41
+ export async function readInstalledManifest(root, packageName) {
42
+ const require = createRequire(join(resolve(root), 'package.json'));
43
+ for (const subpath of ['manifest.json', 'manifest']) {
44
+ try {
45
+ const path = require.resolve(`${packageName}/${subpath}`);
46
+ const manifest = (await readJson(path));
47
+ if (manifest && typeof manifest === 'object' && manifest.packageName) {
48
+ return manifest;
49
+ }
50
+ }
51
+ catch {
52
+ // Not exported or not installed: try the next subpath.
53
+ }
54
+ }
55
+ return null;
56
+ }
57
+ /** Read the manifests of `packages`, skipping those that have none. */
58
+ export async function readInstalledManifests(root, packages) {
59
+ const names = packages ?? (await manifestPackages(root));
60
+ const found = await Promise.all(names.map((name) => readInstalledManifest(root, name)));
61
+ return found.filter((m) => m !== null);
62
+ }
63
+ /**
64
+ * Load and validate the project's cookbook and resolve it against the
65
+ * installed packages' recipes. Throws when the cookbook is missing or invalid
66
+ * (the message lists every problem), including a recipe no installed package
67
+ * declares.
68
+ */
69
+ export async function loadCookbookApp(options = {}) {
70
+ const root = resolve(options.root ?? process.cwd());
71
+ const file = options.file ?? COOKBOOK_FILE;
72
+ const validate = options.validate ?? (await defaultValidator());
73
+ let document;
74
+ try {
75
+ document = await readJson(join(root, file));
76
+ }
77
+ catch (error) {
78
+ throw new Error(`Cannot read ${file}: ${error instanceof Error ? error.message : String(error)}`);
79
+ }
80
+ const manifests = await readInstalledManifests(root, options.packages);
81
+ const full = catalogFromManifests(manifests);
82
+ const result = validate(document, {
83
+ recipes: full.recipes.map((r) => r.id),
84
+ });
85
+ if (!result.ok) {
86
+ throw new Error(`${file} is not a valid cookbook:\n- ${result.errors.join('\n- ')}`);
87
+ }
88
+ const { cookbook } = result;
89
+ const warnings = [...(result.warnings ?? [])];
90
+ return {
91
+ cookbook,
92
+ catalog: narrowCatalog(full, {
93
+ recipes: cookbook.recipes,
94
+ features: cookbook.features ?? [],
95
+ }),
96
+ warnings,
97
+ };
98
+ }
99
+ /** Whether `root` has a cookbook file (for apps that fall back to a plain shell). */
100
+ export async function hasCookbook(root = process.cwd(), file = COOKBOOK_FILE) {
101
+ try {
102
+ await access(join(resolve(root), file));
103
+ return true;
104
+ }
105
+ catch {
106
+ return false;
107
+ }
108
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * The cookbook's `theme` as the shell applies it (#3749). Pure: registering a
3
+ * brand colour with smrt-ui is the component's job (`brand-theme.ts`).
4
+ */
5
+ import type { CookbookTheme } from '@happyvertical/smrt-types';
6
+ import type { ResolvedCookbookTheme } from './types.js';
7
+ export declare const DEFAULT_THEME_PRESET = "smrt";
8
+ export declare const DEFAULT_COLOR_SCHEME: "system";
9
+ /** The fonts a brand theme may name, each with its CSS stack. A fixed list, never free text. */
10
+ export declare const THEME_FONTS: Readonly<Record<string, string>>;
11
+ /** `#rgb` or `#rrggbb` (with or without `#`) as lowercase `#rrggbb`; else null. */
12
+ export declare function normalizeHex(value: unknown): string | null;
13
+ /** The brand theme's id: unique per colour and font, since a registered id never changes. */
14
+ export declare function brandThemeId(primary: string, fontFamily?: string): string;
15
+ /**
16
+ * The preset and scheme a theme means. Lenient: a bad colour or font is
17
+ * ignored rather than throwing, because a hand-edited file must still render
18
+ * (`validateCookbook` is where it is rejected).
19
+ */
20
+ export declare function resolveCookbookTheme(theme: CookbookTheme | undefined): ResolvedCookbookTheme;
21
+ //# sourceMappingURL=theme.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../../src/components/cookbook/theme.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAExD,eAAO,MAAM,oBAAoB,SAAS,CAAC;AAC3C,eAAO,MAAM,oBAAoB,EAAG,QAAiB,CAAC;AAEtD,gGAAgG;AAChG,eAAO,MAAM,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAMxD,CAAC;AAIF,mFAAmF;AACnF,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAO1D;AAED,6FAA6F;AAC7F,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAKzE;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,aAAa,GAAG,SAAS,GAC/B,qBAAqB,CAmBvB"}
@@ -0,0 +1,53 @@
1
+ export const DEFAULT_THEME_PRESET = 'smrt';
2
+ export const DEFAULT_COLOR_SCHEME = 'system';
3
+ /** The fonts a brand theme may name, each with its CSS stack. A fixed list, never free text. */
4
+ export const THEME_FONTS = {
5
+ 'system-ui': 'system-ui, -apple-system, "Segoe UI", sans-serif',
6
+ Inter: 'Inter, system-ui, sans-serif',
7
+ Georgia: 'Georgia, "Times New Roman", serif',
8
+ 'ui-rounded': 'ui-rounded, "SF Pro Rounded", system-ui, sans-serif',
9
+ 'ui-monospace': 'ui-monospace, "SF Mono", Menlo, monospace',
10
+ };
11
+ const HEX = /^#?([0-9a-f]{3}|[0-9a-f]{6})$/i;
12
+ /** `#rgb` or `#rrggbb` (with or without `#`) as lowercase `#rrggbb`; else null. */
13
+ export function normalizeHex(value) {
14
+ if (typeof value !== 'string')
15
+ return null;
16
+ const match = HEX.exec(value.trim());
17
+ if (!match)
18
+ return null;
19
+ let digits = match[1].toLowerCase();
20
+ if (digits.length === 3)
21
+ digits = [...digits].map((d) => d + d).join('');
22
+ return `#${digits}`;
23
+ }
24
+ /** The brand theme's id: unique per colour and font, since a registered id never changes. */
25
+ export function brandThemeId(primary, fontFamily) {
26
+ const font = fontFamily
27
+ ? `-${fontFamily.toLowerCase().replace(/[^a-z0-9]/g, '')}`
28
+ : '';
29
+ return `cookbook-brand-${primary.replace('#', '')}${font}`;
30
+ }
31
+ /**
32
+ * The preset and scheme a theme means. Lenient: a bad colour or font is
33
+ * ignored rather than throwing, because a hand-edited file must still render
34
+ * (`validateCookbook` is where it is rejected).
35
+ */
36
+ export function resolveCookbookTheme(theme) {
37
+ const colorScheme = theme?.colorScheme === 'light' || theme?.colorScheme === 'dark'
38
+ ? theme.colorScheme
39
+ : DEFAULT_COLOR_SCHEME;
40
+ const primary = theme?.custom ? normalizeHex(theme.custom.primary) : null;
41
+ if (theme?.custom && primary) {
42
+ const font = theme.custom.fontFamily;
43
+ const fontFamily = typeof font === 'string' && Object.hasOwn(THEME_FONTS, font)
44
+ ? font
45
+ : undefined;
46
+ return {
47
+ preset: brandThemeId(primary, fontFamily),
48
+ colorScheme,
49
+ brand: { primary, ...(fontFamily ? { fontFamily } : {}) },
50
+ };
51
+ }
52
+ return { preset: theme?.preset || DEFAULT_THEME_PRESET, colorScheme };
53
+ }
@@ -0,0 +1,204 @@
1
+ /**
2
+ * Inputs and outputs of the cookbook app shell (#3749).
3
+ *
4
+ * Everything here is plain data: the builder takes a cookbook plus a recipe
5
+ * catalog and returns shell configuration; nothing imports Svelte or the DOM.
6
+ */
7
+ import type { Cookbook, CookbookPolicyRow, RecipeDefinition, RecipeShellSlot, RecipeWidgetSurface } from '@happyvertical/smrt-types';
8
+ import type { ComponentProps } from 'svelte';
9
+ import type AppShell from '../app/AppShell.svelte';
10
+ import type { RecipeExportResolver } from '../overview/recipe-widgets.js';
11
+ import type { OverviewDefinition } from '../overview/types.js';
12
+ import type { CoreWidgetLoaders } from '../overview/widgets/core.js';
13
+ import type { ShellLayout } from '../workspace/admin-shell/layout.js';
14
+ import type { ShellNavGroup } from '../workspace/admin-shell/types.js';
15
+ /**
16
+ * The part of a recipe the shell reads. A manifest `RecipeDefinition` fits;
17
+ * hosts may drop `help`, `synonyms` and other bulk before serializing.
18
+ */
19
+ export type CookbookRecipe = Pick<RecipeDefinition, 'id' | 'label' | 'nav' | 'models'> & Partial<Pick<RecipeDefinition, 'group' | 'section' | 'surfaces' | 'requires' | 'requiresAny'>>;
20
+ /** What the shell needs to know about one model. */
21
+ export interface CookbookModelInfo {
22
+ /** Qualified name, `@scope/pkg:Class`. */
23
+ id: string;
24
+ /** Class name, e.g. `Order`. */
25
+ name: string;
26
+ /** Package id used in item ids and routes: `commerce` for `@happyvertical/smrt-commerce`. */
27
+ packageId: string;
28
+ /** The model's own description, for an entry with no description of its own. */
29
+ description?: string;
30
+ /** Has an API, MCP or CLI surface; only exposed models get a feature entry. */
31
+ exposed?: boolean;
32
+ }
33
+ /** Recipes plus the models they point at: the catalog a cookbook resolves against. */
34
+ export interface CookbookCatalog {
35
+ recipes: readonly CookbookRecipe[];
36
+ models: readonly CookbookModelInfo[];
37
+ }
38
+ /** One navigation entry: a layout item id and the model page it opens. */
39
+ export interface CookbookEntry {
40
+ /** Layout item id: `item:<package>:<Model>` or `item:<package>:<Model>:<key>`. */
41
+ id: string;
42
+ label: string;
43
+ icon: string;
44
+ description: string;
45
+ model: CookbookModelInfo;
46
+ /** In-app path of the entry's page, without any host base. */
47
+ path: string;
48
+ /** Link the nav uses (`path` through `entryHref`). */
49
+ href: string;
50
+ /** Explicit noun for the New button. */
51
+ noun?: string;
52
+ /** Row filter of a keyed entry. */
53
+ filter?: {
54
+ field: string;
55
+ value: string;
56
+ };
57
+ /** Recipe that contributed the entry; `null` for a feature model. */
58
+ recipeId: string | null;
59
+ }
60
+ /** A suggested navigation section and what it holds. */
61
+ export interface CookbookSection {
62
+ /** Layout id: `section:<id>`. */
63
+ id: string;
64
+ label: string;
65
+ icon?: string;
66
+ description?: string;
67
+ /** Entry ids, in recipe order. */
68
+ entryIds: string[];
69
+ /** Ids of the recipes that suggest the section. */
70
+ recipeIds: string[];
71
+ /** In-app path of the section page. */
72
+ path: string;
73
+ }
74
+ /** A recipe surface placed into a shell slot. */
75
+ export interface CookbookShellWidget {
76
+ recipeId: string;
77
+ slot: RecipeShellSlot;
78
+ /** `'<module specifier>#<ExportName>'`; the host resolves it. */
79
+ export: `${string}#${string}`;
80
+ label: string;
81
+ icon?: string;
82
+ }
83
+ export interface CookbookRouteSurface {
84
+ recipeId: string;
85
+ path: string;
86
+ export: `${string}#${string}`;
87
+ label: string;
88
+ }
89
+ export interface CookbookSettingsPanel {
90
+ recipeId: string;
91
+ export: `${string}#${string}`;
92
+ label: string;
93
+ }
94
+ /** The theme as the shell applies it; a brand colour is registered by the component. */
95
+ export interface ResolvedCookbookTheme {
96
+ /** Preset id: a built-in smrt-ui preset, or the brand theme's id. */
97
+ preset: string;
98
+ colorScheme: 'light' | 'dark' | 'system';
99
+ /** Present when the cookbook names a brand colour (it wins over `preset`). */
100
+ brand?: {
101
+ primary: string;
102
+ fontFamily?: string;
103
+ };
104
+ }
105
+ /** One section page: its overview definition and the cookbook's saved override. */
106
+ export interface CookbookOverviewPage {
107
+ definition: OverviewDefinition;
108
+ /** The cookbook's stored override for this page, if any (untrusted JSON). */
109
+ override: unknown;
110
+ }
111
+ export interface BuildCookbookShellOptions {
112
+ cookbook: Cookbook;
113
+ /** Recipes and models, usually from {@link catalogFromManifests}. */
114
+ catalog: CookbookCatalog;
115
+ /** The app name shown in the shell brand. */
116
+ title?: string;
117
+ /**
118
+ * Recipe order, when it differs from the cookbook's (the cookbook lists ids
119
+ * sorted). Recipes it does not list follow in cookbook order. Section order
120
+ * follows the first recipe of each section, then the cookbook layout.
121
+ */
122
+ recipeOrder?: readonly string[];
123
+ /** In-app path of a model entry; default `/m/<package>/<Model>/[key/]`. */
124
+ entryPath?: (entry: {
125
+ packageId: string;
126
+ modelName: string;
127
+ key?: string;
128
+ }) => string;
129
+ /** In-app path of a section page; default `/s/<slug>/`. */
130
+ sectionPath?: (sectionId: string) => string;
131
+ /** Prefix for every generated href (`/app` or an app query helper). */
132
+ href?: (path: string) => string;
133
+ /**
134
+ * Put a record count and the latest records on every section page. They need
135
+ * `metric` and `records` loaders on the host; without them leave this off
136
+ * and the page shows the entries as shortcut cards only.
137
+ */
138
+ dataWidgets?: boolean;
139
+ /** Where the app's settings page lives; passed through to the shell. */
140
+ settingsHref?: string;
141
+ }
142
+ /** Everything `AppShell` and the section pages need, derived from a cookbook. */
143
+ export interface CookbookShell {
144
+ title: string;
145
+ navMode: 'sections';
146
+ /** Sections as the shell takes them (layout is applied by the shell). */
147
+ navGroups: ShellNavGroup[];
148
+ /** The cookbook's layout, or `null` when it has none. */
149
+ layout: ShellLayout | null;
150
+ /** Suggested sections in order, whether or not the layout hides them. */
151
+ sections: CookbookSection[];
152
+ /** Every entry by layout item id. */
153
+ entries: ReadonlyMap<string, CookbookEntry>;
154
+ theme: ResolvedCookbookTheme;
155
+ /** Section page overviews by section id (`section:sales`, `custom:shop`). */
156
+ overviews: Record<string, CookbookOverviewPage>;
157
+ /** Recipe `shell-widget` surfaces, for the host to resolve into `slotItems`. */
158
+ shellWidgets: CookbookShellWidget[];
159
+ routes: CookbookRouteSurface[];
160
+ settingsPanels: CookbookSettingsPanel[];
161
+ /** Recipe `widget` surfaces, for `registerRecipeWidgets`. */
162
+ widgets: Array<Pick<RecipeDefinition, 'id'> & {
163
+ surfaces: RecipeWidgetSurface[];
164
+ }>;
165
+ /** The cookbook's app-scope field policy rows, applied by the runtime. */
166
+ policies: CookbookPolicyRow[];
167
+ settingsHref?: string;
168
+ /** Layout id to section page path (the shell's `sectionHref`). */
169
+ sectionPath: (sectionId: string) => string;
170
+ /** Problems that did not stop the build (unknown recipes, models, ...). */
171
+ issues: string[];
172
+ }
173
+ /** Props of `CookbookSectionPage`. */
174
+ export interface CookbookSectionPageProps {
175
+ /** The layout id (`section:sales`, `custom:shop`). */
176
+ sectionId?: string;
177
+ /** The route slug (`section-sales`); used when `sectionId` is absent. */
178
+ slug?: string;
179
+ /** Extra content under the overview. */
180
+ children?: import('svelte').Snippet;
181
+ }
182
+ /** Props of `CookbookApp`; anything else is passed to `AppShell` unchanged. */
183
+ export interface CookbookAppProps extends Omit<ComponentProps<typeof AppShell>, 'navGroups' | 'nav' | 'navMode' | 'layout' | 'onlayoutchange' | 'preset' | 'colorScheme' | 'sectionHref' | 'title' | 'children'>, Pick<BuildCookbookShellOptions, 'recipeOrder' | 'entryPath' | 'sectionPath' | 'href' | 'title'> {
184
+ cookbook: Cookbook;
185
+ catalog: CookbookCatalog;
186
+ /**
187
+ * Data loaders for the `metric`, `records` and `chart` widgets. With
188
+ * `metric` and `records`, section pages also show a record count and the
189
+ * latest records of the section's lead model.
190
+ */
191
+ loaders?: Omit<CoreWidgetLoaders, 'shortcuts'>;
192
+ /** Host capabilities handed to widget loaders that run in the browser. */
193
+ widgetContext?: () => Record<string, unknown>;
194
+ /**
195
+ * Turns a recipe export reference (`'@acme/shop/svelte#SalesTotal'`) into
196
+ * the export: a static map of dynamic imports in a bundled app. Without it,
197
+ * recipe `widget` and `shell-widget` surfaces are ignored.
198
+ */
199
+ resolveExport?: RecipeExportResolver;
200
+ /** Called with the cookbook after a layout or overview edit. */
201
+ oncookbookchange?: (cookbook: Cookbook) => void;
202
+ children: import('svelte').Snippet;
203
+ }
204
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/cookbook/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EACV,QAAQ,EACR,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,mBAAmB,EACpB,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,KAAK,QAAQ,MAAM,wBAAwB,CAAC;AACnD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAC1E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAC;AACtE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAEvE;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,IAAI,CAC/B,gBAAgB,EAChB,IAAI,GAAG,OAAO,GAAG,KAAK,GAAG,QAAQ,CAClC,GACC,OAAO,CACL,IAAI,CACF,gBAAgB,EAChB,OAAO,GAAG,SAAS,GAAG,UAAU,GAAG,UAAU,GAAG,aAAa,CAC9D,CACF,CAAC;AAEJ,oDAAoD;AACpD,MAAM,WAAW,iBAAiB;IAChC,0CAA0C;IAC1C,EAAE,EAAE,MAAM,CAAC;IACX,gCAAgC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,6FAA6F;IAC7F,SAAS,EAAE,MAAM,CAAC;IAClB,gFAAgF;IAChF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+EAA+E;IAC/E,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,sFAAsF;AACtF,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,SAAS,cAAc,EAAE,CAAC;IACnC,MAAM,EAAE,SAAS,iBAAiB,EAAE,CAAC;CACtC;AAED,0EAA0E;AAC1E,MAAM,WAAW,aAAa;IAC5B,kFAAkF;IAClF,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,iBAAiB,CAAC;IACzB,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAC;IACb,sDAAsD;IACtD,IAAI,EAAE,MAAM,CAAC;IACb,wCAAwC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mCAAmC;IACnC,MAAM,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1C,qEAAqE;IACrE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,wDAAwD;AACxD,MAAM,WAAW,eAAe;IAC9B,iCAAiC;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kCAAkC;IAClC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,mDAAmD;IACnD,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,iDAAiD;AACjD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,eAAe,CAAC;IACtB,iEAAiE;IACjE,MAAM,EAAE,GAAG,MAAM,IAAI,MAAM,EAAE,CAAC;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,GAAG,MAAM,IAAI,MAAM,EAAE,CAAC;IAC9B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,GAAG,MAAM,IAAI,MAAM,EAAE,CAAC;IAC9B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wFAAwF;AACxF,MAAM,WAAW,qBAAqB;IACpC,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;IACzC,8EAA8E;IAC9E,KAAK,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAClD;AAED,mFAAmF;AACnF,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,kBAAkB,CAAC;IAC/B,6EAA6E;IAC7E,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,QAAQ,CAAC;IACnB,qEAAqE;IACrE,OAAO,EAAE,eAAe,CAAC;IACzB,6CAA6C;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,2EAA2E;IAC3E,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,KAAK,MAAM,CAAC;IACb,2DAA2D;IAC3D,WAAW,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC;IAC5C,uEAAuE;IACvE,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAChC;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,wEAAwE;IACxE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,iFAAiF;AACjF,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,UAAU,CAAC;IACpB,yEAAyE;IACzE,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,yDAAyD;IACzD,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3B,yEAAyE;IACzE,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,qCAAqC;IACrC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC5C,KAAK,EAAE,qBAAqB,CAAC;IAC7B,6EAA6E;IAC7E,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;IAChD,gFAAgF;IAChF,YAAY,EAAE,mBAAmB,EAAE,CAAC;IACpC,MAAM,EAAE,oBAAoB,EAAE,CAAC;IAC/B,cAAc,EAAE,qBAAqB,EAAE,CAAC;IACxC,6DAA6D;IAC7D,OAAO,EAAE,KAAK,CACZ,IAAI,CAAC,gBAAgB,EAAE,IAAI,CAAC,GAAG;QAAE,QAAQ,EAAE,mBAAmB,EAAE,CAAA;KAAE,CACnE,CAAC;IACF,0EAA0E;IAC1E,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kEAAkE;IAClE,WAAW,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC;IAC3C,2EAA2E;IAC3E,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,sCAAsC;AACtC,MAAM,WAAW,wBAAwB;IACvC,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yEAAyE;IACzE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,QAAQ,CAAC,EAAE,OAAO,QAAQ,EAAE,OAAO,CAAC;CACrC;AAED,+EAA+E;AAC/E,MAAM,WAAW,gBACf,SAAQ,IAAI,CACR,cAAc,CAAC,OAAO,QAAQ,CAAC,EAC7B,WAAW,GACX,KAAK,GACL,SAAS,GACT,QAAQ,GACR,gBAAgB,GAChB,QAAQ,GACR,aAAa,GACb,aAAa,GACb,OAAO,GACP,UAAU,CACb,EACD,IAAI,CACF,yBAAyB,EACzB,aAAa,GAAG,WAAW,GAAG,aAAa,GAAG,MAAM,GAAG,OAAO,CAC/D;IACH,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,eAAe,CAAC;IACzB;;;;OAIG;IACH,OAAO,CAAC,EAAE,IAAI,CAAC,iBAAiB,EAAE,WAAW,CAAC,CAAC;IAC/C,0EAA0E;IAC1E,aAAa,CAAC,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9C;;;;OAIG;IACH,aAAa,CAAC,EAAE,oBAAoB,CAAC;IACrC,gEAAgE;IAChE,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;IAChD,QAAQ,EAAE,OAAO,QAAQ,EAAE,OAAO,CAAC;CACpC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,16 @@
1
+ <script lang="ts">
2
+ import { type I18nStore, setI18nContext } from '@happyvertical/smrt-ui/i18n';
3
+ import { untrack } from 'svelte';
4
+ import MailboxDemo from '../../../../messages/src/svelte/components/MailboxDemo.svelte';
5
+ import NotificationBell from './NotificationBell.svelte';
6
+ import type { NotificationProvider } from './types.js';
7
+
8
+ interface Props {
9
+ store: I18nStore;
10
+ provider?: NotificationProvider;
11
+ mailbox?: boolean;
12
+ }
13
+ let { store, provider, mailbox = false }: Props = $props();
14
+ setI18nContext(untrack(() => store));
15
+ </script>
16
+ {#if mailbox}<MailboxDemo />{:else if provider}<NotificationBell {provider} />{/if}
@@ -0,0 +1,11 @@
1
+ import { type I18nStore } from '@happyvertical/smrt-ui/i18n';
2
+ import type { NotificationProvider } from './types.js';
3
+ interface Props {
4
+ store: I18nStore;
5
+ provider?: NotificationProvider;
6
+ mailbox?: boolean;
7
+ }
8
+ declare const LocalizedNotifications: import("svelte").Component<Props, {}, "">;
9
+ type LocalizedNotifications = ReturnType<typeof LocalizedNotifications>;
10
+ export default LocalizedNotifications;
11
+ //# sourceMappingURL=LocalizedNotifications.fixture.svelte.d.ts.map