@shipfox/client-shell 11.0.0 → 12.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/dist/compose/compose-client-features.d.ts +2 -1
  2. package/dist/compose/compose-client-features.d.ts.map +1 -1
  3. package/dist/compose/compose-client-features.js +5 -3
  4. package/dist/compose/compose-client-features.js.map +1 -1
  5. package/dist/compose/compose-routes.d.ts +6 -2
  6. package/dist/compose/compose-routes.d.ts.map +1 -1
  7. package/dist/compose/compose-routes.js +137 -2
  8. package/dist/compose/compose-routes.js.map +1 -1
  9. package/dist/compose/errors.d.ts +4 -0
  10. package/dist/compose/errors.d.ts.map +1 -1
  11. package/dist/compose/errors.js +6 -0
  12. package/dist/compose/errors.js.map +1 -1
  13. package/dist/compose/validate-registries.d.ts +9 -2
  14. package/dist/compose/validate-registries.d.ts.map +1 -1
  15. package/dist/compose/validate-registries.js +83 -2
  16. package/dist/compose/validate-registries.js.map +1 -1
  17. package/dist/contract.d.ts +23 -3
  18. package/dist/contract.d.ts.map +1 -1
  19. package/dist/contract.js.map +1 -1
  20. package/dist/runtime/anchor-paths.d.ts +2 -0
  21. package/dist/runtime/anchor-paths.d.ts.map +1 -1
  22. package/dist/runtime/anchor-paths.js +15 -0
  23. package/dist/runtime/anchor-paths.js.map +1 -1
  24. package/dist/runtime/assemble-route-tree.d.ts +3 -2
  25. package/dist/runtime/assemble-route-tree.d.ts.map +1 -1
  26. package/dist/runtime/assemble-route-tree.js +76 -5
  27. package/dist/runtime/assemble-route-tree.js.map +1 -1
  28. package/dist/runtime/index.d.ts +1 -0
  29. package/dist/runtime/index.d.ts.map +1 -1
  30. package/dist/runtime/index.js +1 -0
  31. package/dist/runtime/index.js.map +1 -1
  32. package/dist/runtime/layout-navigation.d.ts +7 -0
  33. package/dist/runtime/layout-navigation.d.ts.map +1 -0
  34. package/dist/runtime/layout-navigation.js +18 -0
  35. package/dist/runtime/layout-navigation.js.map +1 -0
  36. package/dist/runtime/provider-stack.d.ts.map +1 -1
  37. package/dist/runtime/provider-stack.js +7 -3
  38. package/dist/runtime/provider-stack.js.map +1 -1
  39. package/dist/runtime/registries.d.ts +2 -1
  40. package/dist/runtime/registries.d.ts.map +1 -1
  41. package/dist/runtime/registries.js +10 -0
  42. package/dist/runtime/registries.js.map +1 -1
  43. package/dist/tsconfig.test.tsbuildinfo +1 -1
  44. package/dist/vite/generate.d.ts +3 -2
  45. package/dist/vite/generate.d.ts.map +1 -1
  46. package/dist/vite/generate.js +108 -20
  47. package/dist/vite/generate.js.map +1 -1
  48. package/dist/vite/plugin.d.ts.map +1 -1
  49. package/dist/vite/plugin.js +7 -3
  50. package/dist/vite/plugin.js.map +1 -1
  51. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"anchor-paths.d.ts","sourceRoot":"","sources":["../../src/runtime/anchor-paths.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,WAAW;;;;;CAKP,CAAC;AAEX,OAAO,EAAC,WAAW,EAAC,CAAC;AAErB,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,OAAO,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQ7F"}
1
+ {"version":3,"file":"anchor-paths.d.ts","sourceRoot":"","sources":["../../src/runtime/anchor-paths.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,cAAc,CAAC;AAEhD,QAAA,MAAM,WAAW;;;;;CAKP,CAAC;AAEX,OAAO,EAAC,WAAW,EAAC,CAAC;AAErB,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,OAAO,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQ7F;AAED,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,MAAM,EAChB,WAAW,GAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAa,GACnD,MAAM,CAiBR"}
@@ -1,3 +1,4 @@
1
+ import { normalizeRoutePath } from '#compose/normalize-route-path.js';
1
2
  const anchorPaths = {
2
3
  root: '/',
3
4
  workspaceLayout: '/workspaces/$wid',
@@ -14,5 +15,19 @@ export function routePathForAnchor(anchor, fullPath) {
14
15
  }
15
16
  return fullPath.slice(anchorPath.length);
16
17
  }
18
+ export function routePathForParent(parent, fullPath, layoutPaths = new Map()) {
19
+ const normalizedPath = normalizeRoutePath(fullPath);
20
+ const parentPath = Object.hasOwn(anchorPaths, parent) ? anchorPaths[parent] : layoutPaths.get(parent);
21
+ if (!parentPath) {
22
+ throw new Error(`Route "${normalizedPath}" targets missing layout parent "${parent}".`);
23
+ }
24
+ if (parentPath === '/') return normalizedPath;
25
+ if (normalizedPath === parentPath) return '/';
26
+ if (parentPath !== '/' && !normalizedPath.startsWith(`${parentPath}/`)) {
27
+ const parentKind = Object.hasOwn(anchorPaths, parent) ? 'anchor' : 'layout';
28
+ throw new Error(`Route "${normalizedPath}" must be nested under ${parentKind} "${parent}" (${parentPath}).`);
29
+ }
30
+ return normalizedPath.slice(parentPath.length);
31
+ }
17
32
 
18
33
  //# sourceMappingURL=anchor-paths.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/runtime/anchor-paths.ts"],"sourcesContent":["const anchorPaths = {\n root: '/',\n workspaceLayout: '/workspaces/$wid',\n projectLayout: '/workspaces/$wid/projects/$pid',\n workspaceSettings: '/workspaces/$wid/settings',\n} as const;\n\nexport {anchorPaths};\n\nexport function routePathForAnchor(anchor: keyof typeof anchorPaths, fullPath: string): string {\n const anchorPath = anchorPaths[anchor];\n if (anchor === 'root') return fullPath;\n if (fullPath === anchorPath) return '/';\n if (!fullPath.startsWith(`${anchorPath}/`)) {\n throw new Error(`Route \"${fullPath}\" must be nested under anchor \"${anchor}\" (${anchorPath}).`);\n }\n return fullPath.slice(anchorPath.length);\n}\n"],"names":["anchorPaths","root","workspaceLayout","projectLayout","workspaceSettings","routePathForAnchor","anchor","fullPath","anchorPath","startsWith","Error","slice","length"],"mappings":"AAAA,MAAMA,cAAc;IAClBC,MAAM;IACNC,iBAAiB;IACjBC,eAAe;IACfC,mBAAmB;AACrB;AAEA,SAAQJ,WAAW,GAAE;AAErB,OAAO,SAASK,mBAAmBC,MAAgC,EAAEC,QAAgB;IACnF,MAAMC,aAAaR,WAAW,CAACM,OAAO;IACtC,IAAIA,WAAW,QAAQ,OAAOC;IAC9B,IAAIA,aAAaC,YAAY,OAAO;IACpC,IAAI,CAACD,SAASE,UAAU,CAAC,GAAGD,WAAW,CAAC,CAAC,GAAG;QAC1C,MAAM,IAAIE,MAAM,CAAC,OAAO,EAAEH,SAAS,+BAA+B,EAAED,OAAO,GAAG,EAAEE,WAAW,EAAE,CAAC;IAChG;IACA,OAAOD,SAASI,KAAK,CAACH,WAAWI,MAAM;AACzC"}
1
+ {"version":3,"sources":["../../src/runtime/anchor-paths.ts"],"sourcesContent":["import {normalizeRoutePath} from '#compose/normalize-route-path.js';\nimport type {RouteParentId} from '#contract.js';\n\nconst anchorPaths = {\n root: '/',\n workspaceLayout: '/workspaces/$wid',\n projectLayout: '/workspaces/$wid/projects/$pid',\n workspaceSettings: '/workspaces/$wid/settings',\n} as const;\n\nexport {anchorPaths};\n\nexport function routePathForAnchor(anchor: keyof typeof anchorPaths, fullPath: string): string {\n const anchorPath = anchorPaths[anchor];\n if (anchor === 'root') return fullPath;\n if (fullPath === anchorPath) return '/';\n if (!fullPath.startsWith(`${anchorPath}/`)) {\n throw new Error(`Route \"${fullPath}\" must be nested under anchor \"${anchor}\" (${anchorPath}).`);\n }\n return fullPath.slice(anchorPath.length);\n}\n\nexport function routePathForParent(\n parent: RouteParentId,\n fullPath: string,\n layoutPaths: ReadonlyMap<string, string> = new Map(),\n): string {\n const normalizedPath = normalizeRoutePath(fullPath);\n const parentPath = Object.hasOwn(anchorPaths, parent)\n ? anchorPaths[parent as keyof typeof anchorPaths]\n : layoutPaths.get(parent);\n if (!parentPath) {\n throw new Error(`Route \"${normalizedPath}\" targets missing layout parent \"${parent}\".`);\n }\n if (parentPath === '/') return normalizedPath;\n if (normalizedPath === parentPath) return '/';\n if (parentPath !== '/' && !normalizedPath.startsWith(`${parentPath}/`)) {\n const parentKind = Object.hasOwn(anchorPaths, parent) ? 'anchor' : 'layout';\n throw new Error(\n `Route \"${normalizedPath}\" must be nested under ${parentKind} \"${parent}\" (${parentPath}).`,\n );\n }\n return normalizedPath.slice(parentPath.length);\n}\n"],"names":["normalizeRoutePath","anchorPaths","root","workspaceLayout","projectLayout","workspaceSettings","routePathForAnchor","anchor","fullPath","anchorPath","startsWith","Error","slice","length","routePathForParent","parent","layoutPaths","Map","normalizedPath","parentPath","Object","hasOwn","get","parentKind"],"mappings":"AAAA,SAAQA,kBAAkB,QAAO,mCAAmC;AAGpE,MAAMC,cAAc;IAClBC,MAAM;IACNC,iBAAiB;IACjBC,eAAe;IACfC,mBAAmB;AACrB;AAEA,SAAQJ,WAAW,GAAE;AAErB,OAAO,SAASK,mBAAmBC,MAAgC,EAAEC,QAAgB;IACnF,MAAMC,aAAaR,WAAW,CAACM,OAAO;IACtC,IAAIA,WAAW,QAAQ,OAAOC;IAC9B,IAAIA,aAAaC,YAAY,OAAO;IACpC,IAAI,CAACD,SAASE,UAAU,CAAC,GAAGD,WAAW,CAAC,CAAC,GAAG;QAC1C,MAAM,IAAIE,MAAM,CAAC,OAAO,EAAEH,SAAS,+BAA+B,EAAED,OAAO,GAAG,EAAEE,WAAW,EAAE,CAAC;IAChG;IACA,OAAOD,SAASI,KAAK,CAACH,WAAWI,MAAM;AACzC;AAEA,OAAO,SAASC,mBACdC,MAAqB,EACrBP,QAAgB,EAChBQ,cAA2C,IAAIC,KAAK;IAEpD,MAAMC,iBAAiBlB,mBAAmBQ;IAC1C,MAAMW,aAAaC,OAAOC,MAAM,CAACpB,aAAac,UAC1Cd,WAAW,CAACc,OAAmC,GAC/CC,YAAYM,GAAG,CAACP;IACpB,IAAI,CAACI,YAAY;QACf,MAAM,IAAIR,MAAM,CAAC,OAAO,EAAEO,eAAe,iCAAiC,EAAEH,OAAO,EAAE,CAAC;IACxF;IACA,IAAII,eAAe,KAAK,OAAOD;IAC/B,IAAIA,mBAAmBC,YAAY,OAAO;IAC1C,IAAIA,eAAe,OAAO,CAACD,eAAeR,UAAU,CAAC,GAAGS,WAAW,CAAC,CAAC,GAAG;QACtE,MAAMI,aAAaH,OAAOC,MAAM,CAACpB,aAAac,UAAU,WAAW;QACnE,MAAM,IAAIJ,MACR,CAAC,OAAO,EAAEO,eAAe,uBAAuB,EAAEK,WAAW,EAAE,EAAER,OAAO,GAAG,EAAEI,WAAW,EAAE,CAAC;IAE/F;IACA,OAAOD,eAAeN,KAAK,CAACO,WAAWN,MAAM;AAC/C"}
@@ -1,10 +1,11 @@
1
- import type { ComposedRoute } from '#compose/compose-routes.js';
1
+ import type { ComposedLayout, ComposedRoute } from '#compose/compose-routes.js';
2
2
  import { buildAnchorSkeleton } from '#runtime/anchors.js';
3
3
  import type { RouteImpl } from '#runtime/define-route.js';
4
4
  export type ResolveRouteImpl = (specifier: string) => RouteImpl | Promise<RouteImpl>;
5
5
  export declare function assembleRouteTree(routes: readonly ComposedRoute[], options: {
6
+ layouts?: readonly ComposedLayout[];
6
7
  resolveImpl: ResolveRouteImpl;
7
8
  navigation: Parameters<typeof buildAnchorSkeleton>[0]['navigation'];
8
9
  settingsSections: Parameters<typeof buildAnchorSkeleton>[0]['settingsSections'];
9
- }): Promise<import("@tanstack/router-core").Route<import("@tanstack/router-core").Register, any, "/", "/", string, "__root__", undefined, {}, import("./router-context").RouterContext, import("@tanstack/router-core").AnyContext, import("@tanstack/router-core").AnyContext, {}, undefined, readonly [...import("@tanstack/react-router").Route<unknown, import("@tanstack/router-core").AnyRoute, "/", "/" | `/${any}/`, string, "/" | `/${any}/`, undefined, import("@tanstack/router-core").ResolveParams<"/">, import("@tanstack/router-core").AnyContext, import("@tanstack/router-core").AnyContext, import("@tanstack/router-core").AnyContext, {}, undefined, unknown, unknown, unknown, unknown, undefined>[], import("@tanstack/router-core").Route<unknown, import("@tanstack/react-router").RootRoute<import("@tanstack/router-core").Register, undefined, import("./router-context").RouterContext, import("@tanstack/router-core").AnyContext, import("@tanstack/router-core").AnyContext, {}, undefined, unknown, unknown, unknown, unknown, undefined>, "/workspaces/$wid", "/workspaces/$wid", string, "/workspaces/$wid", undefined, import("@tanstack/router-core").ResolveParams<"/workspaces/$wid">, import("@tanstack/router-core").AnyContext, import("@tanstack/router-core").AnyContext, ({ context, params, location }: import("@tanstack/router-core").BeforeLoadContextOptions<unknown, import("@tanstack/react-router").RootRoute<import("@tanstack/router-core").Register, undefined, import("./router-context").RouterContext, import("@tanstack/router-core").AnyContext, import("@tanstack/router-core").AnyContext, {}, undefined, unknown, unknown, unknown, unknown, undefined>, undefined, import("@tanstack/router-core").ResolveParams<"/workspaces/$wid">, import("@tanstack/router-core").AnyContext, import("@tanstack/router-core").AnyContext, "/workspaces/$wid", unknown, undefined>) => Promise<import("./workspace-setup").WorkspaceSetupState | undefined>, {}, undefined, readonly [...import("@tanstack/react-router").Route<unknown, import("@tanstack/router-core").AnyRoute, "/", "/" | `/${any}/`, string, "/" | `/${any}/`, undefined, import("@tanstack/router-core").ResolveParams<"/">, import("@tanstack/router-core").AnyContext, import("@tanstack/router-core").AnyContext, import("@tanstack/router-core").AnyContext, {}, undefined, unknown, unknown, unknown, unknown, undefined>[], import("@tanstack/router-core").Route<unknown, import("@tanstack/react-router").Route<unknown, import("@tanstack/react-router").RootRoute<import("@tanstack/router-core").Register, undefined, import("./router-context").RouterContext, import("@tanstack/router-core").AnyContext, import("@tanstack/router-core").AnyContext, {}, undefined, unknown, unknown, unknown, unknown, undefined>, "/workspaces/$wid", "/workspaces/$wid", string, "/workspaces/$wid", undefined, import("@tanstack/router-core").ResolveParams<"/workspaces/$wid">, import("@tanstack/router-core").AnyContext, import("@tanstack/router-core").AnyContext, ({ context, params, location }: import("@tanstack/router-core").BeforeLoadContextOptions<unknown, import("@tanstack/react-router").RootRoute<import("@tanstack/router-core").Register, undefined, import("./router-context").RouterContext, import("@tanstack/router-core").AnyContext, import("@tanstack/router-core").AnyContext, {}, undefined, unknown, unknown, unknown, unknown, undefined>, undefined, import("@tanstack/router-core").ResolveParams<"/workspaces/$wid">, import("@tanstack/router-core").AnyContext, import("@tanstack/router-core").AnyContext, "/workspaces/$wid", unknown, undefined>) => Promise<import("./workspace-setup").WorkspaceSetupState | undefined>, {}, undefined, unknown, unknown, unknown, unknown, undefined>, "/projects/$pid", "/workspaces/$wid/projects/$pid", string, "/workspaces/$wid/projects/$pid", undefined, import("@tanstack/router-core").ResolveParams<"/projects/$pid">, import("@tanstack/router-core").AnyContext, import("@tanstack/router-core").AnyContext, import("@tanstack/router-core").AnyContext, {}, undefined, import("@tanstack/react-router").Route<unknown, import("@tanstack/router-core").AnyRoute, "/", "/" | `/${any}/`, string, "/" | `/${any}/`, undefined, import("@tanstack/router-core").ResolveParams<"/">, import("@tanstack/router-core").AnyContext, import("@tanstack/router-core").AnyContext, import("@tanstack/router-core").AnyContext, {}, undefined, unknown, unknown, unknown, unknown, undefined>[], unknown, unknown, unknown, undefined>, import("@tanstack/router-core").Route<unknown, import("@tanstack/react-router").Route<unknown, import("@tanstack/react-router").RootRoute<import("@tanstack/router-core").Register, undefined, import("./router-context").RouterContext, import("@tanstack/router-core").AnyContext, import("@tanstack/router-core").AnyContext, {}, undefined, unknown, unknown, unknown, unknown, undefined>, "/workspaces/$wid", "/workspaces/$wid", string, "/workspaces/$wid", undefined, import("@tanstack/router-core").ResolveParams<"/workspaces/$wid">, import("@tanstack/router-core").AnyContext, import("@tanstack/router-core").AnyContext, ({ context, params, location }: import("@tanstack/router-core").BeforeLoadContextOptions<unknown, import("@tanstack/react-router").RootRoute<import("@tanstack/router-core").Register, undefined, import("./router-context").RouterContext, import("@tanstack/router-core").AnyContext, import("@tanstack/router-core").AnyContext, {}, undefined, unknown, unknown, unknown, unknown, undefined>, undefined, import("@tanstack/router-core").ResolveParams<"/workspaces/$wid">, import("@tanstack/router-core").AnyContext, import("@tanstack/router-core").AnyContext, "/workspaces/$wid", unknown, undefined>) => Promise<import("./workspace-setup").WorkspaceSetupState | undefined>, {}, undefined, unknown, unknown, unknown, unknown, undefined>, "/settings", "/workspaces/$wid/settings", string, "/workspaces/$wid/settings", undefined, import("@tanstack/router-core").ResolveParams<"/settings">, import("@tanstack/router-core").AnyContext, import("@tanstack/router-core").AnyContext, import("@tanstack/router-core").AnyContext, {}, undefined, import("@tanstack/react-router").Route<unknown, import("@tanstack/router-core").AnyRoute, "/", "/" | `/${any}/`, string, "/" | `/${any}/`, undefined, import("@tanstack/router-core").ResolveParams<"/">, import("@tanstack/router-core").AnyContext, import("@tanstack/router-core").AnyContext, import("@tanstack/router-core").AnyContext, {}, undefined, unknown, unknown, unknown, unknown, undefined>[], unknown, unknown, unknown, undefined>], unknown, unknown, unknown, undefined>], unknown, unknown, unknown, undefined>>;
10
+ }): Promise<import("@tanstack/react-router").RootRoute<import("@tanstack/router-core").Register, undefined, import("./router-context").RouterContext, import("@tanstack/router-core").AnyContext, import("@tanstack/router-core").AnyContext, {}, undefined, unknown, unknown, unknown, unknown, undefined>>;
10
11
  //# sourceMappingURL=assemble-route-tree.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"assemble-route-tree.d.ts","sourceRoot":"","sources":["../../src/runtime/assemble-route-tree.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAC,mBAAmB,EAAqB,MAAM,qBAAqB,CAAC;AAC5E,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,0BAA0B,CAAC;AAExD,MAAM,MAAM,gBAAgB,GAAG,CAAC,SAAS,EAAE,MAAM,KAAK,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;AAErF,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,SAAS,aAAa,EAAE,EAChC,OAAO,EAAE;IACP,WAAW,EAAE,gBAAgB,CAAC;IAC9B,UAAU,EAAE,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;IACpE,gBAAgB,EAAE,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC;CACjF,o+MA4BF"}
1
+ {"version":3,"file":"assemble-route-tree.d.ts","sourceRoot":"","sources":["../../src/runtime/assemble-route-tree.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,cAAc,EAAE,aAAa,EAAC,MAAM,4BAA4B,CAAC;AAG9E,OAAO,EAAC,mBAAmB,EAAC,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,0BAA0B,CAAC;AAExD,MAAM,MAAM,gBAAgB,GAAG,CAAC,SAAS,EAAE,MAAM,KAAK,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;AAkCrF,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,SAAS,aAAa,EAAE,EAChC,OAAO,EAAE;IACP,OAAO,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;IACpC,WAAW,EAAE,gBAAgB,CAAC;IAC9B,UAAU,EAAE,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;IACpE,gBAAgB,EAAE,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC;CACjF,4SA8EF"}
@@ -1,19 +1,90 @@
1
1
  import { createRoute } from '@tanstack/react-router';
2
- import { buildAnchorSkeleton, routePathForAnchor } from '#runtime/anchors.js';
2
+ import { routePathForParent } from '#runtime/anchor-paths.js';
3
+ import { buildAnchorSkeleton } from '#runtime/anchors.js';
4
+ const shellAnchors = [
5
+ 'root',
6
+ 'workspaceLayout',
7
+ 'projectLayout',
8
+ 'workspaceSettings'
9
+ ];
10
+ function isShellAnchor(parent) {
11
+ return shellAnchors.includes(parent);
12
+ }
13
+ function orderLayouts(layouts) {
14
+ const byId = new Map(layouts.map((layout)=>[
15
+ layout.id,
16
+ layout
17
+ ]));
18
+ const ordered = [];
19
+ const visiting = new Set();
20
+ const visited = new Set();
21
+ function visit(layout) {
22
+ if (visited.has(layout.id)) return;
23
+ if (!isShellAnchor(layout.parent)) {
24
+ if (visiting.has(layout.id)) throw new Error(`Layout "${layout.id}" has a cyclic parent reference.`);
25
+ const parent = byId.get(layout.parent);
26
+ if (!parent) throw new Error(`Layout "${layout.id}" targets missing parent "${layout.parent}".`);
27
+ visiting.add(layout.id);
28
+ visit(parent);
29
+ visiting.delete(layout.id);
30
+ }
31
+ visited.add(layout.id);
32
+ ordered.push(layout);
33
+ }
34
+ for (const layout of layouts)visit(layout);
35
+ return ordered;
36
+ }
3
37
  export async function assembleRouteTree(routes, options) {
38
+ const layouts = orderLayouts(options.layouts ?? []);
39
+ const layoutPaths = new Map(layouts.map((layout)=>[
40
+ layout.id,
41
+ layout.path
42
+ ]));
4
43
  const skeleton = buildAnchorSkeleton(options);
5
- const children = await Promise.all(routes.map(async (route)=>{
44
+ const layoutRoutes = new Map();
45
+ for (const layout of layouts){
46
+ const impl = await options.resolveImpl(layout.impl);
47
+ const parentRoute = isShellAnchor(layout.parent) ? skeleton.anchors[layout.parent] : layoutRoutes.get(layout.parent);
48
+ if (!parentRoute) throw new Error(`Missing layout parent "${layout.parent}".`);
49
+ layoutRoutes.set(layout.id, createRoute({
50
+ getParentRoute: ()=>parentRoute,
51
+ path: routePathForParent(layout.parent, layout.path, layoutPaths),
52
+ ...impl.options
53
+ }));
54
+ }
55
+ const routeEntries = await Promise.all(routes.map(async (route)=>{
6
56
  const impl = await options.resolveImpl(route.impl);
57
+ const parentRoute = isShellAnchor(route.parent) ? skeleton.anchors[route.parent] : layoutRoutes.get(route.parent);
58
+ if (!parentRoute) throw new Error(`Missing route parent "${route.parent}".`);
7
59
  return {
8
60
  parent: route.parent,
9
61
  route: createRoute({
10
- getParentRoute: ()=>skeleton.anchors[route.parent],
11
- path: routePathForAnchor(route.parent, route.path),
62
+ getParentRoute: ()=>parentRoute,
63
+ path: routePathForParent(route.parent, route.path, layoutPaths),
12
64
  ...impl.options
13
65
  })
14
66
  };
15
67
  }));
16
- const childrenFor = (anchor)=>children.filter((child)=>child.parent === anchor).map((child)=>child.route);
68
+ const routeChildrenFor = (parent)=>routeEntries.filter((entry)=>entry.parent === parent).map((entry)=>entry.route);
69
+ const layoutTrees = new Map();
70
+ function layoutTree(layoutId) {
71
+ const existing = layoutTrees.get(layoutId);
72
+ if (existing) return existing;
73
+ const layout = layouts.find((candidate)=>candidate.id === layoutId);
74
+ const route = layoutRoutes.get(layoutId);
75
+ if (!layout || !route) throw new Error(`Missing layout "${layoutId}".`);
76
+ const children = [
77
+ ...routeChildrenFor(layoutId),
78
+ ...layouts.filter((candidate)=>candidate.parent === layoutId).map((candidate)=>layoutTree(candidate.id))
79
+ ];
80
+ const tree = route.addChildren(children);
81
+ layoutTrees.set(layoutId, tree);
82
+ return tree;
83
+ }
84
+ const childrenFor = (parent)=>[
85
+ ...routeChildrenFor(parent),
86
+ ...layouts.filter((layout)=>layout.parent === parent).map((layout)=>layoutTree(layout.id))
87
+ ];
17
88
  const projectLayout = skeleton.projectLayout.addChildren(childrenFor('projectLayout'));
18
89
  const workspaceSettings = skeleton.workspaceSettings.addChildren(childrenFor('workspaceSettings'));
19
90
  const workspaceLayout = skeleton.workspaceLayout.addChildren([
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/runtime/assemble-route-tree.ts"],"sourcesContent":["import {createRoute} from '@tanstack/react-router';\nimport type {ComposedRoute} from '#compose/compose-routes.js';\nimport {buildAnchorSkeleton, routePathForAnchor} from '#runtime/anchors.js';\nimport type {RouteImpl} from '#runtime/define-route.js';\n\nexport type ResolveRouteImpl = (specifier: string) => RouteImpl | Promise<RouteImpl>;\n\nexport async function assembleRouteTree(\n routes: readonly ComposedRoute[],\n options: {\n resolveImpl: ResolveRouteImpl;\n navigation: Parameters<typeof buildAnchorSkeleton>[0]['navigation'];\n settingsSections: Parameters<typeof buildAnchorSkeleton>[0]['settingsSections'];\n },\n) {\n const skeleton = buildAnchorSkeleton(options);\n const children = await Promise.all(\n routes.map(async (route) => {\n const impl = await options.resolveImpl(route.impl);\n return {\n parent: route.parent,\n route: createRoute({\n getParentRoute: () => skeleton.anchors[route.parent] as never,\n path: routePathForAnchor(route.parent, route.path),\n ...impl.options,\n } as never),\n };\n }),\n );\n const childrenFor = (anchor: keyof typeof skeleton.anchors) =>\n children.filter((child) => child.parent === anchor).map((child) => child.route);\n const projectLayout = skeleton.projectLayout.addChildren(childrenFor('projectLayout'));\n const workspaceSettings = skeleton.workspaceSettings.addChildren(\n childrenFor('workspaceSettings'),\n );\n const workspaceLayout = skeleton.workspaceLayout.addChildren([\n ...childrenFor('workspaceLayout'),\n projectLayout,\n workspaceSettings,\n ]);\n return skeleton.rootRoute.addChildren([...childrenFor('root'), workspaceLayout]);\n}\n"],"names":["createRoute","buildAnchorSkeleton","routePathForAnchor","assembleRouteTree","routes","options","skeleton","children","Promise","all","map","route","impl","resolveImpl","parent","getParentRoute","anchors","path","childrenFor","anchor","filter","child","projectLayout","addChildren","workspaceSettings","workspaceLayout","rootRoute"],"mappings":"AAAA,SAAQA,WAAW,QAAO,yBAAyB;AAEnD,SAAQC,mBAAmB,EAAEC,kBAAkB,QAAO,sBAAsB;AAK5E,OAAO,eAAeC,kBACpBC,MAAgC,EAChCC,OAIC;IAED,MAAMC,WAAWL,oBAAoBI;IACrC,MAAME,WAAW,MAAMC,QAAQC,GAAG,CAChCL,OAAOM,GAAG,CAAC,OAAOC;QAChB,MAAMC,OAAO,MAAMP,QAAQQ,WAAW,CAACF,MAAMC,IAAI;QACjD,OAAO;YACLE,QAAQH,MAAMG,MAAM;YACpBH,OAAOX,YAAY;gBACjBe,gBAAgB,IAAMT,SAASU,OAAO,CAACL,MAAMG,MAAM,CAAC;gBACpDG,MAAMf,mBAAmBS,MAAMG,MAAM,EAAEH,MAAMM,IAAI;gBACjD,GAAGL,KAAKP,OAAO;YACjB;QACF;IACF;IAEF,MAAMa,cAAc,CAACC,SACnBZ,SAASa,MAAM,CAAC,CAACC,QAAUA,MAAMP,MAAM,KAAKK,QAAQT,GAAG,CAAC,CAACW,QAAUA,MAAMV,KAAK;IAChF,MAAMW,gBAAgBhB,SAASgB,aAAa,CAACC,WAAW,CAACL,YAAY;IACrE,MAAMM,oBAAoBlB,SAASkB,iBAAiB,CAACD,WAAW,CAC9DL,YAAY;IAEd,MAAMO,kBAAkBnB,SAASmB,eAAe,CAACF,WAAW,CAAC;WACxDL,YAAY;QACfI;QACAE;KACD;IACD,OAAOlB,SAASoB,SAAS,CAACH,WAAW,CAAC;WAAIL,YAAY;QAASO;KAAgB;AACjF"}
1
+ {"version":3,"sources":["../../src/runtime/assemble-route-tree.ts"],"sourcesContent":["import {type AnyRoute, createRoute} from '@tanstack/react-router';\nimport type {ComposedLayout, ComposedRoute} from '#compose/compose-routes.js';\nimport type {RouteParentId} from '#contract.js';\nimport {routePathForParent} from '#runtime/anchor-paths.js';\nimport {buildAnchorSkeleton} from '#runtime/anchors.js';\nimport type {RouteImpl} from '#runtime/define-route.js';\n\nexport type ResolveRouteImpl = (specifier: string) => RouteImpl | Promise<RouteImpl>;\n\nconst shellAnchors = ['root', 'workspaceLayout', 'projectLayout', 'workspaceSettings'] as const;\n\nfunction isShellAnchor(parent: RouteParentId): parent is (typeof shellAnchors)[number] {\n return shellAnchors.includes(parent as (typeof shellAnchors)[number]);\n}\n\nfunction orderLayouts(layouts: readonly ComposedLayout[]): ComposedLayout[] {\n const byId = new Map(layouts.map((layout) => [layout.id, layout]));\n const ordered: ComposedLayout[] = [];\n const visiting = new Set<string>();\n const visited = new Set<string>();\n\n function visit(layout: ComposedLayout): void {\n if (visited.has(layout.id)) return;\n if (!isShellAnchor(layout.parent)) {\n if (visiting.has(layout.id))\n throw new Error(`Layout \"${layout.id}\" has a cyclic parent reference.`);\n const parent = byId.get(layout.parent);\n if (!parent)\n throw new Error(`Layout \"${layout.id}\" targets missing parent \"${layout.parent}\".`);\n visiting.add(layout.id);\n visit(parent);\n visiting.delete(layout.id);\n }\n visited.add(layout.id);\n ordered.push(layout);\n }\n\n for (const layout of layouts) visit(layout);\n return ordered;\n}\n\nexport async function assembleRouteTree(\n routes: readonly ComposedRoute[],\n options: {\n layouts?: readonly ComposedLayout[];\n resolveImpl: ResolveRouteImpl;\n navigation: Parameters<typeof buildAnchorSkeleton>[0]['navigation'];\n settingsSections: Parameters<typeof buildAnchorSkeleton>[0]['settingsSections'];\n },\n) {\n const layouts = orderLayouts(options.layouts ?? []);\n const layoutPaths = new Map(layouts.map((layout) => [layout.id, layout.path]));\n const skeleton = buildAnchorSkeleton(options);\n const layoutRoutes = new Map<string, AnyRoute>();\n\n for (const layout of layouts) {\n const impl = await options.resolveImpl(layout.impl);\n const parentRoute = isShellAnchor(layout.parent)\n ? skeleton.anchors[layout.parent]\n : layoutRoutes.get(layout.parent);\n if (!parentRoute) throw new Error(`Missing layout parent \"${layout.parent}\".`);\n layoutRoutes.set(\n layout.id,\n createRoute({\n getParentRoute: () => parentRoute as never,\n path: routePathForParent(layout.parent, layout.path, layoutPaths),\n ...impl.options,\n } as never) as unknown as AnyRoute,\n );\n }\n\n const routeEntries: Array<{parent: RouteParentId; route: AnyRoute}> = await Promise.all(\n routes.map(async (route) => {\n const impl = await options.resolveImpl(route.impl);\n const parentRoute = isShellAnchor(route.parent)\n ? skeleton.anchors[route.parent]\n : layoutRoutes.get(route.parent);\n if (!parentRoute) throw new Error(`Missing route parent \"${route.parent}\".`);\n return {\n parent: route.parent,\n route: createRoute({\n getParentRoute: () => parentRoute as never,\n path: routePathForParent(route.parent, route.path, layoutPaths),\n ...impl.options,\n } as never) as unknown as AnyRoute,\n };\n }),\n );\n\n const routeChildrenFor = (parent: RouteParentId) =>\n routeEntries.filter((entry) => entry.parent === parent).map((entry) => entry.route);\n const layoutTrees = new Map<string, AnyRoute>();\n function layoutTree(layoutId: string): AnyRoute {\n const existing = layoutTrees.get(layoutId);\n if (existing) return existing;\n const layout = layouts.find((candidate) => candidate.id === layoutId);\n const route = layoutRoutes.get(layoutId);\n if (!layout || !route) throw new Error(`Missing layout \"${layoutId}\".`);\n const children = [\n ...routeChildrenFor(layoutId),\n ...layouts\n .filter((candidate) => candidate.parent === layoutId)\n .map((candidate) => layoutTree(candidate.id)),\n ];\n const tree = route.addChildren(children as never) as unknown as AnyRoute;\n layoutTrees.set(layoutId, tree);\n return tree;\n }\n\n const childrenFor = (parent: RouteParentId) => [\n ...routeChildrenFor(parent),\n ...layouts.filter((layout) => layout.parent === parent).map((layout) => layoutTree(layout.id)),\n ];\n const projectLayout = skeleton.projectLayout.addChildren(childrenFor('projectLayout') as never);\n const workspaceSettings = skeleton.workspaceSettings.addChildren(\n childrenFor('workspaceSettings') as never,\n );\n const workspaceLayout = skeleton.workspaceLayout.addChildren([\n ...childrenFor('workspaceLayout'),\n projectLayout,\n workspaceSettings,\n ] as never);\n return skeleton.rootRoute.addChildren([\n ...childrenFor('root'),\n workspaceLayout,\n ] as never) as unknown as typeof skeleton.rootRoute;\n}\n"],"names":["createRoute","routePathForParent","buildAnchorSkeleton","shellAnchors","isShellAnchor","parent","includes","orderLayouts","layouts","byId","Map","map","layout","id","ordered","visiting","Set","visited","visit","has","Error","get","add","delete","push","assembleRouteTree","routes","options","layoutPaths","path","skeleton","layoutRoutes","impl","resolveImpl","parentRoute","anchors","set","getParentRoute","routeEntries","Promise","all","route","routeChildrenFor","filter","entry","layoutTrees","layoutTree","layoutId","existing","find","candidate","children","tree","addChildren","childrenFor","projectLayout","workspaceSettings","workspaceLayout","rootRoute"],"mappings":"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"}
@@ -18,6 +18,7 @@ export * from './chrome-context.js';
18
18
  export * from './compose-client-app.js';
19
19
  export * from './define-route.js';
20
20
  export * from './last-workspace.js';
21
+ export * from './layout-navigation.js';
21
22
  export * from './nav-order.js';
22
23
  export * from './route-inputs.js';
23
24
  export * from './router-context.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAE,SAAS,EAAE,KAAK,cAAc,EAAC,MAAM,2BAA2B,CAAC;AACtF,OAAO,EAAC,cAAc,EAAE,KAAK,mBAAmB,EAAC,MAAM,gCAAgC,CAAC;AACxF,OAAO,EAAC,iBAAiB,EAAC,MAAM,mCAAmC,CAAC;AACpE,YAAY,EACV,oBAAoB,EACpB,YAAY,EACZ,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAC,sBAAsB,EAAE,cAAc,EAAC,MAAM,8BAA8B,CAAC;AACpF,cAAc,uCAAuC,CAAC;AACtD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,sBAAsB,CAAC;AACrC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oCAAoC,CAAC;AACnD,cAAc,kCAAkC,CAAC;AACjD,cAAc,mCAAmC,CAAC;AAClD,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAE,SAAS,EAAE,KAAK,cAAc,EAAC,MAAM,2BAA2B,CAAC;AACtF,OAAO,EAAC,cAAc,EAAE,KAAK,mBAAmB,EAAC,MAAM,gCAAgC,CAAC;AACxF,OAAO,EAAC,iBAAiB,EAAC,MAAM,mCAAmC,CAAC;AACpE,YAAY,EACV,oBAAoB,EACpB,YAAY,EACZ,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAC,sBAAsB,EAAE,cAAc,EAAC,MAAM,8BAA8B,CAAC;AACpF,cAAc,uCAAuC,CAAC;AACtD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,sBAAsB,CAAC;AACrC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oCAAoC,CAAC;AACnD,cAAc,kCAAkC,CAAC;AACjD,cAAc,mCAAmC,CAAC;AAClD,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC"}
@@ -17,6 +17,7 @@ export * from './chrome-context.js';
17
17
  export * from './compose-client-app.js';
18
18
  export * from './define-route.js';
19
19
  export * from './last-workspace.js';
20
+ export * from './layout-navigation.js';
20
21
  export * from './nav-order.js';
21
22
  export * from './route-inputs.js';
22
23
  export * from './router-context.js';
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/runtime/index.ts"],"sourcesContent":["export {AuthActions, AuthShell, type AuthShellProps} from '#components/auth-shell.js';\nexport {WorkspaceCrumb, type WorkspaceCrumbProps} from '#components/workspace-crumb.js';\nexport {WorkspaceSwitcher} from '#components/workspace-switcher.js';\nexport type {\n AuthenticatedSession,\n UserIdentity,\n WorkspaceMembership,\n WorkspaceSummary,\n} from '#core/session.js';\nexport {toAuthenticatedSession, toUserIdentity} from '#hooks/api/session-mapper.js';\nexport * from '../compose/compose-client-features.js';\nexport * from '../compose/compose-routes.js';\nexport * from '../compose/errors.js';\nexport * from '../compose/merge-config.js';\nexport * from '../compose/normalize-route-path.js';\nexport * from '../compose/validate-providers.js';\nexport * from '../compose/validate-registries.js';\nexport * from './active-workspace.js';\nexport * from './anchor-paths.js';\nexport * from './anchors.js';\nexport * from './auth.js';\nexport * from './chrome-context.js';\nexport * from './compose-client-app.js';\nexport * from './define-route.js';\nexport * from './last-workspace.js';\nexport * from './nav-order.js';\nexport * from './route-inputs.js';\nexport * from './router-context.js';\nexport * from './workspace-setup.js';\n"],"names":["AuthActions","AuthShell","WorkspaceCrumb","WorkspaceSwitcher","toAuthenticatedSession","toUserIdentity"],"mappings":"AAAA,SAAQA,WAAW,EAAEC,SAAS,QAA4B,4BAA4B;AACtF,SAAQC,cAAc,QAAiC,iCAAiC;AACxF,SAAQC,iBAAiB,QAAO,oCAAoC;AAOpE,SAAQC,sBAAsB,EAAEC,cAAc,QAAO,+BAA+B;AACpF,cAAc,wCAAwC;AACtD,cAAc,+BAA+B;AAC7C,cAAc,uBAAuB;AACrC,cAAc,6BAA6B;AAC3C,cAAc,qCAAqC;AACnD,cAAc,mCAAmC;AACjD,cAAc,oCAAoC;AAClD,cAAc,wBAAwB;AACtC,cAAc,oBAAoB;AAClC,cAAc,eAAe;AAC7B,cAAc,YAAY;AAC1B,cAAc,sBAAsB;AACpC,cAAc,0BAA0B;AACxC,cAAc,oBAAoB;AAClC,cAAc,sBAAsB;AACpC,cAAc,iBAAiB;AAC/B,cAAc,oBAAoB;AAClC,cAAc,sBAAsB;AACpC,cAAc,uBAAuB"}
1
+ {"version":3,"sources":["../../src/runtime/index.ts"],"sourcesContent":["export {AuthActions, AuthShell, type AuthShellProps} from '#components/auth-shell.js';\nexport {WorkspaceCrumb, type WorkspaceCrumbProps} from '#components/workspace-crumb.js';\nexport {WorkspaceSwitcher} from '#components/workspace-switcher.js';\nexport type {\n AuthenticatedSession,\n UserIdentity,\n WorkspaceMembership,\n WorkspaceSummary,\n} from '#core/session.js';\nexport {toAuthenticatedSession, toUserIdentity} from '#hooks/api/session-mapper.js';\nexport * from '../compose/compose-client-features.js';\nexport * from '../compose/compose-routes.js';\nexport * from '../compose/errors.js';\nexport * from '../compose/merge-config.js';\nexport * from '../compose/normalize-route-path.js';\nexport * from '../compose/validate-providers.js';\nexport * from '../compose/validate-registries.js';\nexport * from './active-workspace.js';\nexport * from './anchor-paths.js';\nexport * from './anchors.js';\nexport * from './auth.js';\nexport * from './chrome-context.js';\nexport * from './compose-client-app.js';\nexport * from './define-route.js';\nexport * from './last-workspace.js';\nexport * from './layout-navigation.js';\nexport * from './nav-order.js';\nexport * from './route-inputs.js';\nexport * from './router-context.js';\nexport * from './workspace-setup.js';\n"],"names":["AuthActions","AuthShell","WorkspaceCrumb","WorkspaceSwitcher","toAuthenticatedSession","toUserIdentity"],"mappings":"AAAA,SAAQA,WAAW,EAAEC,SAAS,QAA4B,4BAA4B;AACtF,SAAQC,cAAc,QAAiC,iCAAiC;AACxF,SAAQC,iBAAiB,QAAO,oCAAoC;AAOpE,SAAQC,sBAAsB,EAAEC,cAAc,QAAO,+BAA+B;AACpF,cAAc,wCAAwC;AACtD,cAAc,+BAA+B;AAC7C,cAAc,uBAAuB;AACrC,cAAc,6BAA6B;AAC3C,cAAc,qCAAqC;AACnD,cAAc,mCAAmC;AACjD,cAAc,oCAAoC;AAClD,cAAc,wBAAwB;AACtC,cAAc,oBAAoB;AAClC,cAAc,eAAe;AAC7B,cAAc,YAAY;AAC1B,cAAc,sBAAsB;AACpC,cAAc,0BAA0B;AACxC,cAAc,oBAAoB;AAClC,cAAc,sBAAsB;AACpC,cAAc,yBAAyB;AACvC,cAAc,iBAAiB;AAC/B,cAAc,oBAAoB;AAClC,cAAc,sBAAsB;AACpC,cAAc,uBAAuB"}
@@ -0,0 +1,7 @@
1
+ import type { PropsWithChildren } from 'react';
2
+ import type { ClientFeature, LayoutNavigationEntry } from '#contract.js';
3
+ export declare function LayoutNavigationProvider({ features, children, }: PropsWithChildren<{
4
+ features: readonly ClientFeature[];
5
+ }>): import("react").JSX.Element;
6
+ export declare function useLayoutNavigation(layoutId: string): readonly LayoutNavigationEntry[];
7
+ //# sourceMappingURL=layout-navigation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout-navigation.d.ts","sourceRoot":"","sources":["../../src/runtime/layout-navigation.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,OAAO,CAAC;AAE7C,OAAO,KAAK,EAAC,aAAa,EAAE,qBAAqB,EAAC,MAAM,cAAc,CAAC;AAOvE,wBAAgB,wBAAwB,CAAC,EACvC,QAAQ,EACR,QAAQ,GACT,EAAE,iBAAiB,CAAC;IAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,CAAA;CAAC,CAAC,+BAKzD;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,qBAAqB,EAAE,CAEtF"}
@@ -0,0 +1,18 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { createContext, useContext, useMemo } from 'react';
3
+ import { layoutNavigationRegistry } from './registries.js';
4
+ const LayoutNavigationContext = /*#__PURE__*/ createContext(new Map());
5
+ export function LayoutNavigationProvider({ features, children }) {
6
+ const registry = useMemo(()=>layoutNavigationRegistry(features), [
7
+ features
8
+ ]);
9
+ return /*#__PURE__*/ _jsx(LayoutNavigationContext.Provider, {
10
+ value: registry,
11
+ children: children
12
+ });
13
+ }
14
+ export function useLayoutNavigation(layoutId) {
15
+ return useContext(LayoutNavigationContext).get(layoutId) ?? [];
16
+ }
17
+
18
+ //# sourceMappingURL=layout-navigation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/runtime/layout-navigation.tsx"],"sourcesContent":["import type {PropsWithChildren} from 'react';\nimport {createContext, useContext, useMemo} from 'react';\nimport type {ClientFeature, LayoutNavigationEntry} from '#contract.js';\nimport {layoutNavigationRegistry} from './registries.js';\n\ntype LayoutNavigationRegistry = ReadonlyMap<string, readonly LayoutNavigationEntry[]>;\n\nconst LayoutNavigationContext = createContext<LayoutNavigationRegistry>(new Map());\n\nexport function LayoutNavigationProvider({\n features,\n children,\n}: PropsWithChildren<{features: readonly ClientFeature[]}>) {\n const registry = useMemo(() => layoutNavigationRegistry(features), [features]);\n return (\n <LayoutNavigationContext.Provider value={registry}>{children}</LayoutNavigationContext.Provider>\n );\n}\n\nexport function useLayoutNavigation(layoutId: string): readonly LayoutNavigationEntry[] {\n return useContext(LayoutNavigationContext).get(layoutId) ?? [];\n}\n"],"names":["createContext","useContext","useMemo","layoutNavigationRegistry","LayoutNavigationContext","Map","LayoutNavigationProvider","features","children","registry","Provider","value","useLayoutNavigation","layoutId","get"],"mappings":";AACA,SAAQA,aAAa,EAAEC,UAAU,EAAEC,OAAO,QAAO,QAAQ;AAEzD,SAAQC,wBAAwB,QAAO,kBAAkB;AAIzD,MAAMC,wCAA0BJ,cAAwC,IAAIK;AAE5E,OAAO,SAASC,yBAAyB,EACvCC,QAAQ,EACRC,QAAQ,EACgD;IACxD,MAAMC,WAAWP,QAAQ,IAAMC,yBAAyBI,WAAW;QAACA;KAAS;IAC7E,qBACE,KAACH,wBAAwBM,QAAQ;QAACC,OAAOF;kBAAWD;;AAExD;AAEA,OAAO,SAASI,oBAAoBC,QAAgB;IAClD,OAAOZ,WAAWG,yBAAyBU,GAAG,CAACD,aAAa,EAAE;AAChE"}
@@ -1 +1 @@
1
- {"version":3,"file":"provider-stack.d.ts","sourceRoot":"","sources":["../../src/runtime/provider-stack.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAC,KAAK,WAAW,EAAsB,MAAM,uBAAuB,CAAC;AAC5E,OAAO,EAAC,KAAK,WAAW,EAA4B,MAAM,OAAO,CAAC;AAClE,OAAO,KAAK,EAAC,iBAAiB,EAAY,MAAM,OAAO,CAAC;AACxD,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,cAAc,CAAC;AAChD,OAAO,EAAc,KAAK,gBAAgB,EAAC,MAAM,WAAW,CAAC;AAE7D,KAAK,KAAK,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAE5C,wBAAgB,kBAAkB,CAAC,EACjC,QAAQ,EACR,WAAW,EACX,KAAK,EACL,IAAI,EACJ,QAAQ,GACT,EAAE,iBAAiB,CAAC;IACnB,QAAQ,EAAE,SAAS,aAAa,EAAE,CAAC;IACnC,WAAW,EAAE,WAAW,CAAC;IACzB,KAAK,EAAE,KAAK,CAAC;IACb,IAAI,CAAC,EAAE,IAAI,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC;CAC1C,CAAC,+BAiBD"}
1
+ {"version":3,"file":"provider-stack.d.ts","sourceRoot":"","sources":["../../src/runtime/provider-stack.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAC,KAAK,WAAW,EAAsB,MAAM,uBAAuB,CAAC;AAC5E,OAAO,EAAC,KAAK,WAAW,EAA4B,MAAM,OAAO,CAAC;AAClE,OAAO,KAAK,EAAC,iBAAiB,EAAY,MAAM,OAAO,CAAC;AACxD,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,cAAc,CAAC;AAChD,OAAO,EAAc,KAAK,gBAAgB,EAAC,MAAM,WAAW,CAAC;AAG7D,KAAK,KAAK,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAE5C,wBAAgB,kBAAkB,CAAC,EACjC,QAAQ,EACR,WAAW,EACX,KAAK,EACL,IAAI,EACJ,QAAQ,GACT,EAAE,iBAAiB,CAAC;IACnB,QAAQ,EAAE,SAAS,aAAa,EAAE,CAAC;IACnC,WAAW,EAAE,WAAW,CAAC;IACzB,KAAK,EAAE,KAAK,CAAC;IACb,IAAI,CAAC,EAAE,IAAI,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC;CAC1C,CAAC,+BAmBD"}
@@ -4,6 +4,7 @@ import { TooltipProvider } from '@shipfox/react-ui/tooltip';
4
4
  import { QueryClientProvider } from '@tanstack/react-query';
5
5
  import { Provider as JotaiProvider } from 'jotai';
6
6
  import { AuthRuntime } from './auth.js';
7
+ import { LayoutNavigationProvider } from './layout-navigation.js';
7
8
  export function ShellProviderStack({ features, queryClient, store, auth, children }) {
8
9
  const featureProviders = features.flatMap((feature)=>feature.providers ?? []);
9
10
  const nestedProviders = featureProviders.reduceRight((content, provider)=>/*#__PURE__*/ _jsx(provider.Component, {
@@ -15,9 +16,12 @@ export function ShellProviderStack({ features, queryClient, store, auth, childre
15
16
  client: queryClient,
16
17
  children: /*#__PURE__*/ _jsx(JotaiProvider, {
17
18
  store: store,
18
- children: /*#__PURE__*/ _jsx(AuthRuntime, {
19
- ...auth,
20
- children: nestedProviders
19
+ children: /*#__PURE__*/ _jsx(LayoutNavigationProvider, {
20
+ features: features,
21
+ children: /*#__PURE__*/ _jsx(AuthRuntime, {
22
+ ...auth,
23
+ children: nestedProviders
24
+ })
21
25
  })
22
26
  })
23
27
  })
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/runtime/provider-stack.tsx"],"sourcesContent":["import {ThemeProvider} from '@shipfox/react-ui/theme';\nimport {TooltipProvider} from '@shipfox/react-ui/tooltip';\nimport {type QueryClient, QueryClientProvider} from '@tanstack/react-query';\nimport {type createStore, Provider as JotaiProvider} from 'jotai';\nimport type {PropsWithChildren, ReactNode} from 'react';\nimport type {ClientFeature} from '#contract.js';\nimport {AuthRuntime, type AuthRuntimeProps} from './auth.js';\n\ntype Store = ReturnType<typeof createStore>;\n\nexport function ShellProviderStack({\n features,\n queryClient,\n store,\n auth,\n children,\n}: PropsWithChildren<{\n features: readonly ClientFeature[];\n queryClient: QueryClient;\n store: Store;\n auth?: Pick<AuthRuntimeProps, 'effects'>;\n}>) {\n const featureProviders = features.flatMap((feature) => feature.providers ?? []);\n const nestedProviders = featureProviders.reduceRight<ReactNode>(\n (content, provider) => <provider.Component key={provider.id}>{content}</provider.Component>,\n children,\n );\n return (\n <ThemeProvider>\n <TooltipProvider>\n <QueryClientProvider client={queryClient}>\n <JotaiProvider store={store}>\n <AuthRuntime {...auth}>{nestedProviders}</AuthRuntime>\n </JotaiProvider>\n </QueryClientProvider>\n </TooltipProvider>\n </ThemeProvider>\n );\n}\n"],"names":["ThemeProvider","TooltipProvider","QueryClientProvider","Provider","JotaiProvider","AuthRuntime","ShellProviderStack","features","queryClient","store","auth","children","featureProviders","flatMap","feature","providers","nestedProviders","reduceRight","content","provider","Component","id","client"],"mappings":";AAAA,SAAQA,aAAa,QAAO,0BAA0B;AACtD,SAAQC,eAAe,QAAO,4BAA4B;AAC1D,SAA0BC,mBAAmB,QAAO,wBAAwB;AAC5E,SAA0BC,YAAYC,aAAa,QAAO,QAAQ;AAGlE,SAAQC,WAAW,QAA8B,YAAY;AAI7D,OAAO,SAASC,mBAAmB,EACjCC,QAAQ,EACRC,WAAW,EACXC,KAAK,EACLC,IAAI,EACJC,QAAQ,EAMR;IACA,MAAMC,mBAAmBL,SAASM,OAAO,CAAC,CAACC,UAAYA,QAAQC,SAAS,IAAI,EAAE;IAC9E,MAAMC,kBAAkBJ,iBAAiBK,WAAW,CAClD,CAACC,SAASC,yBAAa,KAACA,SAASC,SAAS;sBAAoBF;WAAdC,SAASE,EAAE,GAC3DV;IAEF,qBACE,KAACX;kBACC,cAAA,KAACC;sBACC,cAAA,KAACC;gBAAoBoB,QAAQd;0BAC3B,cAAA,KAACJ;oBAAcK,OAAOA;8BACpB,cAAA,KAACJ;wBAAa,GAAGK,IAAI;kCAAGM;;;;;;AAMpC"}
1
+ {"version":3,"sources":["../../src/runtime/provider-stack.tsx"],"sourcesContent":["import {ThemeProvider} from '@shipfox/react-ui/theme';\nimport {TooltipProvider} from '@shipfox/react-ui/tooltip';\nimport {type QueryClient, QueryClientProvider} from '@tanstack/react-query';\nimport {type createStore, Provider as JotaiProvider} from 'jotai';\nimport type {PropsWithChildren, ReactNode} from 'react';\nimport type {ClientFeature} from '#contract.js';\nimport {AuthRuntime, type AuthRuntimeProps} from './auth.js';\nimport {LayoutNavigationProvider} from './layout-navigation.js';\n\ntype Store = ReturnType<typeof createStore>;\n\nexport function ShellProviderStack({\n features,\n queryClient,\n store,\n auth,\n children,\n}: PropsWithChildren<{\n features: readonly ClientFeature[];\n queryClient: QueryClient;\n store: Store;\n auth?: Pick<AuthRuntimeProps, 'effects'>;\n}>) {\n const featureProviders = features.flatMap((feature) => feature.providers ?? []);\n const nestedProviders = featureProviders.reduceRight<ReactNode>(\n (content, provider) => <provider.Component key={provider.id}>{content}</provider.Component>,\n children,\n );\n return (\n <ThemeProvider>\n <TooltipProvider>\n <QueryClientProvider client={queryClient}>\n <JotaiProvider store={store}>\n <LayoutNavigationProvider features={features}>\n <AuthRuntime {...auth}>{nestedProviders}</AuthRuntime>\n </LayoutNavigationProvider>\n </JotaiProvider>\n </QueryClientProvider>\n </TooltipProvider>\n </ThemeProvider>\n );\n}\n"],"names":["ThemeProvider","TooltipProvider","QueryClientProvider","Provider","JotaiProvider","AuthRuntime","LayoutNavigationProvider","ShellProviderStack","features","queryClient","store","auth","children","featureProviders","flatMap","feature","providers","nestedProviders","reduceRight","content","provider","Component","id","client"],"mappings":";AAAA,SAAQA,aAAa,QAAO,0BAA0B;AACtD,SAAQC,eAAe,QAAO,4BAA4B;AAC1D,SAA0BC,mBAAmB,QAAO,wBAAwB;AAC5E,SAA0BC,YAAYC,aAAa,QAAO,QAAQ;AAGlE,SAAQC,WAAW,QAA8B,YAAY;AAC7D,SAAQC,wBAAwB,QAAO,yBAAyB;AAIhE,OAAO,SAASC,mBAAmB,EACjCC,QAAQ,EACRC,WAAW,EACXC,KAAK,EACLC,IAAI,EACJC,QAAQ,EAMR;IACA,MAAMC,mBAAmBL,SAASM,OAAO,CAAC,CAACC,UAAYA,QAAQC,SAAS,IAAI,EAAE;IAC9E,MAAMC,kBAAkBJ,iBAAiBK,WAAW,CAClD,CAACC,SAASC,yBAAa,KAACA,SAASC,SAAS;sBAAoBF;WAAdC,SAASE,EAAE,GAC3DV;IAEF,qBACE,KAACZ;kBACC,cAAA,KAACC;sBACC,cAAA,KAACC;gBAAoBqB,QAAQd;0BAC3B,cAAA,KAACL;oBAAcM,OAAOA;8BACpB,cAAA,KAACJ;wBAAyBE,UAAUA;kCAClC,cAAA,KAACH;4BAAa,GAAGM,IAAI;sCAAGM;;;;;;;AAOtC"}
@@ -1,4 +1,5 @@
1
- import type { ClientFeature, NavTabEntry, SettingsSectionEntry } from '#contract.js';
1
+ import type { ClientFeature, LayoutNavigationEntry, NavTabEntry, SettingsSectionEntry } from '#contract.js';
2
2
  export declare function navigationEntries(features: readonly ClientFeature[]): NavTabEntry[];
3
+ export declare function layoutNavigationRegistry(features: readonly ClientFeature[]): ReadonlyMap<string, readonly LayoutNavigationEntry[]>;
3
4
  export declare function settingsEntries(features: readonly ClientFeature[]): SettingsSectionEntry[];
4
5
  //# sourceMappingURL=registries.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"registries.d.ts","sourceRoot":"","sources":["../../src/runtime/registries.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,aAAa,EAAE,WAAW,EAAE,oBAAoB,EAAC,MAAM,cAAc,CAAC;AAgBnF,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,GAAG,WAAW,EAAE,CAWnF;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,GAAG,oBAAoB,EAAE,CAW1F"}
1
+ {"version":3,"file":"registries.d.ts","sourceRoot":"","sources":["../../src/runtime/registries.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,aAAa,EACb,qBAAqB,EACrB,WAAW,EACX,oBAAoB,EACrB,MAAM,cAAc,CAAC;AAgBtB,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,GAAG,WAAW,EAAE,CAWnF;AAED,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,SAAS,aAAa,EAAE,GACjC,WAAW,CAAC,MAAM,EAAE,SAAS,qBAAqB,EAAE,CAAC,CASvD;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,GAAG,oBAAoB,EAAE,CAW1F"}
@@ -12,6 +12,16 @@ export function navigationEntries(features) {
12
12
  to: normalizeRoutePath(entry.to)
13
13
  }));
14
14
  }
15
+ export function layoutNavigationRegistry(features) {
16
+ const registry = new Map();
17
+ for (const entry of navigationEntries(features)){
18
+ if (entry.scope !== 'layout') continue;
19
+ const entries = registry.get(entry.layout) ?? [];
20
+ entries.push(entry);
21
+ registry.set(entry.layout, entries);
22
+ }
23
+ return registry;
24
+ }
15
25
  export function settingsEntries(features) {
16
26
  return features.flatMap((feature, featureIndex)=>(feature.settingsSections ?? []).map((entry, declarationIndex)=>({
17
27
  entry,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/runtime/registries.ts"],"sourcesContent":["import {normalizeRoutePath} from '#compose/normalize-route-path.js';\nimport type {ClientFeature, NavTabEntry, SettingsSectionEntry} from '#contract.js';\n\ninterface Ordered<T> {\n entry: T;\n featureIndex: number;\n declarationIndex: number;\n}\n\nfunction byOrder<T extends {order?: number}>(left: Ordered<T>, right: Ordered<T>): number {\n return (\n (left.entry.order ?? 500) - (right.entry.order ?? 500) ||\n left.featureIndex - right.featureIndex ||\n left.declarationIndex - right.declarationIndex\n );\n}\n\nexport function navigationEntries(features: readonly ClientFeature[]): NavTabEntry[] {\n return features\n .flatMap((feature, featureIndex) =>\n (feature.navigation ?? []).map((entry, declarationIndex) => ({\n entry,\n featureIndex,\n declarationIndex,\n })),\n )\n .sort(byOrder)\n .map(({entry}) => ({...entry, to: normalizeRoutePath(entry.to)}));\n}\n\nexport function settingsEntries(features: readonly ClientFeature[]): SettingsSectionEntry[] {\n return features\n .flatMap((feature, featureIndex) =>\n (feature.settingsSections ?? []).map((entry, declarationIndex) => ({\n entry,\n featureIndex,\n declarationIndex,\n })),\n )\n .sort(byOrder)\n .map(({entry}) => entry);\n}\n"],"names":["normalizeRoutePath","byOrder","left","right","entry","order","featureIndex","declarationIndex","navigationEntries","features","flatMap","feature","navigation","map","sort","to","settingsEntries","settingsSections"],"mappings":"AAAA,SAAQA,kBAAkB,QAAO,mCAAmC;AASpE,SAASC,QAAoCC,IAAgB,EAAEC,KAAiB;IAC9E,OACE,AAACD,CAAAA,KAAKE,KAAK,CAACC,KAAK,IAAI,GAAE,IAAMF,CAAAA,MAAMC,KAAK,CAACC,KAAK,IAAI,GAAE,KACpDH,KAAKI,YAAY,GAAGH,MAAMG,YAAY,IACtCJ,KAAKK,gBAAgB,GAAGJ,MAAMI,gBAAgB;AAElD;AAEA,OAAO,SAASC,kBAAkBC,QAAkC;IAClE,OAAOA,SACJC,OAAO,CAAC,CAACC,SAASL,eACjB,AAACK,CAAAA,QAAQC,UAAU,IAAI,EAAE,AAAD,EAAGC,GAAG,CAAC,CAACT,OAAOG,mBAAsB,CAAA;gBAC3DH;gBACAE;gBACAC;YACF,CAAA,IAEDO,IAAI,CAACb,SACLY,GAAG,CAAC,CAAC,EAACT,KAAK,EAAC,GAAM,CAAA;YAAC,GAAGA,KAAK;YAAEW,IAAIf,mBAAmBI,MAAMW,EAAE;QAAC,CAAA;AAClE;AAEA,OAAO,SAASC,gBAAgBP,QAAkC;IAChE,OAAOA,SACJC,OAAO,CAAC,CAACC,SAASL,eACjB,AAACK,CAAAA,QAAQM,gBAAgB,IAAI,EAAE,AAAD,EAAGJ,GAAG,CAAC,CAACT,OAAOG,mBAAsB,CAAA;gBACjEH;gBACAE;gBACAC;YACF,CAAA,IAEDO,IAAI,CAACb,SACLY,GAAG,CAAC,CAAC,EAACT,KAAK,EAAC,GAAKA;AACtB"}
1
+ {"version":3,"sources":["../../src/runtime/registries.ts"],"sourcesContent":["import {normalizeRoutePath} from '#compose/normalize-route-path.js';\nimport type {\n ClientFeature,\n LayoutNavigationEntry,\n NavTabEntry,\n SettingsSectionEntry,\n} from '#contract.js';\n\ninterface Ordered<T> {\n entry: T;\n featureIndex: number;\n declarationIndex: number;\n}\n\nfunction byOrder<T extends {order?: number}>(left: Ordered<T>, right: Ordered<T>): number {\n return (\n (left.entry.order ?? 500) - (right.entry.order ?? 500) ||\n left.featureIndex - right.featureIndex ||\n left.declarationIndex - right.declarationIndex\n );\n}\n\nexport function navigationEntries(features: readonly ClientFeature[]): NavTabEntry[] {\n return features\n .flatMap((feature, featureIndex) =>\n (feature.navigation ?? []).map((entry, declarationIndex) => ({\n entry,\n featureIndex,\n declarationIndex,\n })),\n )\n .sort(byOrder)\n .map(({entry}) => ({...entry, to: normalizeRoutePath(entry.to)}));\n}\n\nexport function layoutNavigationRegistry(\n features: readonly ClientFeature[],\n): ReadonlyMap<string, readonly LayoutNavigationEntry[]> {\n const registry = new Map<string, LayoutNavigationEntry[]>();\n for (const entry of navigationEntries(features)) {\n if (entry.scope !== 'layout') continue;\n const entries = registry.get(entry.layout) ?? [];\n entries.push(entry);\n registry.set(entry.layout, entries);\n }\n return registry;\n}\n\nexport function settingsEntries(features: readonly ClientFeature[]): SettingsSectionEntry[] {\n return features\n .flatMap((feature, featureIndex) =>\n (feature.settingsSections ?? []).map((entry, declarationIndex) => ({\n entry,\n featureIndex,\n declarationIndex,\n })),\n )\n .sort(byOrder)\n .map(({entry}) => entry);\n}\n"],"names":["normalizeRoutePath","byOrder","left","right","entry","order","featureIndex","declarationIndex","navigationEntries","features","flatMap","feature","navigation","map","sort","to","layoutNavigationRegistry","registry","Map","scope","entries","get","layout","push","set","settingsEntries","settingsSections"],"mappings":"AAAA,SAAQA,kBAAkB,QAAO,mCAAmC;AAcpE,SAASC,QAAoCC,IAAgB,EAAEC,KAAiB;IAC9E,OACE,AAACD,CAAAA,KAAKE,KAAK,CAACC,KAAK,IAAI,GAAE,IAAMF,CAAAA,MAAMC,KAAK,CAACC,KAAK,IAAI,GAAE,KACpDH,KAAKI,YAAY,GAAGH,MAAMG,YAAY,IACtCJ,KAAKK,gBAAgB,GAAGJ,MAAMI,gBAAgB;AAElD;AAEA,OAAO,SAASC,kBAAkBC,QAAkC;IAClE,OAAOA,SACJC,OAAO,CAAC,CAACC,SAASL,eACjB,AAACK,CAAAA,QAAQC,UAAU,IAAI,EAAE,AAAD,EAAGC,GAAG,CAAC,CAACT,OAAOG,mBAAsB,CAAA;gBAC3DH;gBACAE;gBACAC;YACF,CAAA,IAEDO,IAAI,CAACb,SACLY,GAAG,CAAC,CAAC,EAACT,KAAK,EAAC,GAAM,CAAA;YAAC,GAAGA,KAAK;YAAEW,IAAIf,mBAAmBI,MAAMW,EAAE;QAAC,CAAA;AAClE;AAEA,OAAO,SAASC,yBACdP,QAAkC;IAElC,MAAMQ,WAAW,IAAIC;IACrB,KAAK,MAAMd,SAASI,kBAAkBC,UAAW;QAC/C,IAAIL,MAAMe,KAAK,KAAK,UAAU;QAC9B,MAAMC,UAAUH,SAASI,GAAG,CAACjB,MAAMkB,MAAM,KAAK,EAAE;QAChDF,QAAQG,IAAI,CAACnB;QACba,SAASO,GAAG,CAACpB,MAAMkB,MAAM,EAAEF;IAC7B;IACA,OAAOH;AACT;AAEA,OAAO,SAASQ,gBAAgBhB,QAAkC;IAChE,OAAOA,SACJC,OAAO,CAAC,CAACC,SAASL,eACjB,AAACK,CAAAA,QAAQe,gBAAgB,IAAI,EAAE,AAAD,EAAGb,GAAG,CAAC,CAACT,OAAOG,mBAAsB,CAAA;gBACjEH;gBACAE;gBACAC;YACF,CAAA,IAEDO,IAAI,CAACb,SACLY,GAAG,CAAC,CAAC,EAACT,KAAK,EAAC,GAAKA;AACtB"}