@immediately-run/sdk 0.15.0 → 0.17.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 (122) hide show
  1. package/README.md +27 -3
  2. package/dist/MDXProvider.cjs.map +1 -1
  3. package/dist/MDXProvider.d.cts +4 -0
  4. package/dist/MDXProvider.d.ts +4 -0
  5. package/dist/MDXProvider.js.map +1 -1
  6. package/dist/RoutingSpec.cjs.map +1 -1
  7. package/dist/RoutingSpec.d.cts +20 -3
  8. package/dist/RoutingSpec.d.ts +20 -3
  9. package/dist/auth.cjs.map +1 -1
  10. package/dist/auth.d.cts +2 -0
  11. package/dist/auth.d.ts +2 -0
  12. package/dist/auth.js.map +1 -1
  13. package/dist/boot.cjs +17 -7
  14. package/dist/boot.cjs.map +1 -1
  15. package/dist/boot.d.cts +28 -4
  16. package/dist/boot.d.ts +28 -4
  17. package/dist/boot.js +16 -7
  18. package/dist/boot.js.map +1 -1
  19. package/dist/components/Include.cjs.map +1 -1
  20. package/dist/components/Include.d.cts +7 -0
  21. package/dist/components/Include.d.ts +7 -0
  22. package/dist/components/Include.js.map +1 -1
  23. package/dist/components/MDXComponents.cjs.map +1 -1
  24. package/dist/components/MDXComponents.d.cts +6 -0
  25. package/dist/components/MDXComponents.d.ts +6 -0
  26. package/dist/components/MDXComponents.js.map +1 -1
  27. package/dist/components/Routes.cjs +59 -0
  28. package/dist/components/Routes.cjs.map +1 -0
  29. package/dist/components/Routes.d.cts +34 -0
  30. package/dist/components/Routes.d.ts +34 -0
  31. package/dist/components/Routes.js +34 -0
  32. package/dist/components/Routes.js.map +1 -0
  33. package/dist/contribute.cjs.map +1 -1
  34. package/dist/contribute.d.cts +2 -0
  35. package/dist/contribute.d.ts +2 -0
  36. package/dist/contribute.js.map +1 -1
  37. package/dist/debug.cjs +168 -0
  38. package/dist/debug.cjs.map +1 -0
  39. package/dist/debug.d.cts +22 -0
  40. package/dist/debug.d.ts +22 -0
  41. package/dist/debug.js +141 -0
  42. package/dist/debug.js.map +1 -0
  43. package/dist/diagnostics.cjs.map +1 -1
  44. package/dist/diagnostics.d.cts +3 -0
  45. package/dist/diagnostics.d.ts +3 -0
  46. package/dist/diagnostics.js.map +1 -1
  47. package/dist/formFactor.cjs.map +1 -1
  48. package/dist/formFactor.d.cts +2 -0
  49. package/dist/formFactor.d.ts +2 -0
  50. package/dist/formFactor.js.map +1 -1
  51. package/dist/hooks.cjs +27 -28
  52. package/dist/hooks.cjs.map +1 -1
  53. package/dist/hooks.d.cts +39 -4
  54. package/dist/hooks.d.ts +39 -4
  55. package/dist/hooks.js +27 -29
  56. package/dist/hooks.js.map +1 -1
  57. package/dist/index.cjs +6 -0
  58. package/dist/index.cjs.map +1 -1
  59. package/dist/index.d.cts +7 -4
  60. package/dist/index.d.ts +7 -4
  61. package/dist/index.js +3 -0
  62. package/dist/index.js.map +1 -1
  63. package/dist/irMarkers.cjs.map +1 -1
  64. package/dist/irMarkers.d.cts +1 -0
  65. package/dist/irMarkers.d.ts +1 -0
  66. package/dist/irMarkers.js.map +1 -1
  67. package/dist/llm.cjs.map +1 -1
  68. package/dist/llm.d.cts +5 -0
  69. package/dist/llm.d.ts +5 -0
  70. package/dist/llm.js.map +1 -1
  71. package/dist/loading.cjs +186 -0
  72. package/dist/loading.cjs.map +1 -0
  73. package/dist/loading.d.cts +48 -0
  74. package/dist/loading.d.ts +48 -0
  75. package/dist/loading.js +162 -0
  76. package/dist/loading.js.map +1 -0
  77. package/dist/mounts.cjs.map +1 -1
  78. package/dist/mounts.d.cts +3 -1
  79. package/dist/mounts.d.ts +3 -1
  80. package/dist/mounts.js.map +1 -1
  81. package/dist/netFetch.cjs.map +1 -1
  82. package/dist/netFetch.d.cts +2 -0
  83. package/dist/netFetch.d.ts +2 -0
  84. package/dist/netFetch.js.map +1 -1
  85. package/dist/onFsChange.cjs.map +1 -1
  86. package/dist/onFsChange.d.cts +1 -0
  87. package/dist/onFsChange.d.ts +1 -0
  88. package/dist/onFsChange.js.map +1 -1
  89. package/dist/protocolStream.cjs.map +1 -1
  90. package/dist/protocolStream.d.cts +3 -0
  91. package/dist/protocolStream.d.ts +3 -0
  92. package/dist/protocolStream.js.map +1 -1
  93. package/dist/ready.cjs.map +1 -1
  94. package/dist/ready.d.cts +7 -0
  95. package/dist/ready.d.ts +7 -0
  96. package/dist/ready.js.map +1 -1
  97. package/dist/routeMatch.cjs +72 -0
  98. package/dist/routeMatch.cjs.map +1 -0
  99. package/dist/routeMatch.d.cts +19 -0
  100. package/dist/routeMatch.d.ts +19 -0
  101. package/dist/routeMatch.js +46 -0
  102. package/dist/routeMatch.js.map +1 -0
  103. package/dist/routing.cjs +35 -14
  104. package/dist/routing.cjs.map +1 -1
  105. package/dist/routing.d.cts +33 -4
  106. package/dist/routing.d.ts +33 -4
  107. package/dist/routing.js +32 -14
  108. package/dist/routing.js.map +1 -1
  109. package/dist/runtime.cjs.map +1 -1
  110. package/dist/runtime.d.cts +1 -0
  111. package/dist/runtime.d.ts +1 -0
  112. package/dist/runtime.js.map +1 -1
  113. package/dist/sandboxTypes.cjs.map +1 -1
  114. package/dist/sandboxTypes.d.cts +30 -7
  115. package/dist/sandboxTypes.d.ts +30 -7
  116. package/dist/version.cjs +1 -1
  117. package/dist/version.cjs.map +1 -1
  118. package/dist/version.d.cts +1 -1
  119. package/dist/version.d.ts +1 -1
  120. package/dist/version.js +1 -1
  121. package/dist/version.js.map +1 -1
  122. package/package.json +6 -2
@@ -0,0 +1,19 @@
1
+ import { RouteParams } from './RoutingSpec.js';
2
+ import 'react';
3
+
4
+ /**
5
+ * Compile a path template to an anchored RegExp with named groups:
6
+ * `:name` → one non-slash segment `*` → the rest (greedy)
7
+ * A template with neither token is a literal exact match. Raw RegExp patterns
8
+ * never reach here — they are the escape hatch, used as authored.
9
+ */
10
+ declare const compileTemplate: (template: string) => RegExp;
11
+ /** Resolve a pattern to a RegExp: templates are compiled (and cached), RegExp passes through. */
12
+ declare const toRegExp: (pattern: string | RegExp) => RegExp;
13
+ /**
14
+ * Match a `sandboxPath` against a route pattern. Returns the named params on a
15
+ * match (the `*` wildcard surfaces under the `'*'` key), or `null` otherwise.
16
+ */
17
+ declare const matchRoute: (pattern: string | RegExp, path: string) => RouteParams | null;
18
+
19
+ export { compileTemplate, matchRoute, toRegExp };
@@ -0,0 +1,46 @@
1
+ const escapeForRegexp = (str) => str.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&");
2
+ const WILDCARD_GROUP = "wild";
3
+ const compileTemplate = (template) => {
4
+ const token = /(:[A-Za-z_][A-Za-z0-9_]*)|\*/g;
5
+ let src = "";
6
+ let last = 0;
7
+ let m;
8
+ while ((m = token.exec(template)) !== null) {
9
+ src += escapeForRegexp(template.slice(last, m.index));
10
+ src += m[1] ? `(?<${m[1].slice(1)}>[^/]+)` : `(?<${WILDCARD_GROUP}>.*)`;
11
+ last = m.index + m[0].length;
12
+ }
13
+ src += escapeForRegexp(template.slice(last));
14
+ return new RegExp(`^${src}$`);
15
+ };
16
+ const templateCache = /* @__PURE__ */ new Map();
17
+ const toRegExp = (pattern) => {
18
+ if (pattern instanceof RegExp) {
19
+ return pattern;
20
+ }
21
+ let compiled = templateCache.get(pattern);
22
+ if (!compiled) {
23
+ compiled = compileTemplate(pattern);
24
+ templateCache.set(pattern, compiled);
25
+ }
26
+ return compiled;
27
+ };
28
+ const matchRoute = (pattern, path) => {
29
+ const match = path.match(toRegExp(pattern));
30
+ if (!match) {
31
+ return null;
32
+ }
33
+ const params = {};
34
+ for (const [key, value] of Object.entries(match.groups ?? {})) {
35
+ if (value !== void 0) {
36
+ params[key === WILDCARD_GROUP ? "*" : key] = value;
37
+ }
38
+ }
39
+ return params;
40
+ };
41
+ export {
42
+ compileTemplate,
43
+ matchRoute,
44
+ toRegExp
45
+ };
46
+ //# sourceMappingURL=routeMatch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/routeMatch.ts"],"sourcesContent":["import type { RouteParams } from './RoutingSpec';\n\n// from: https://stackoverflow.com/a/63838890\nconst escapeForRegexp = (str: string): string => str.replace(/[.*+\\-?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n// Internal group name standing in for a `*` wildcard (which is not a valid JS\n// regex group identifier); remapped to the `*` param key after matching.\nconst WILDCARD_GROUP = 'wild';\n\n/**\n * Compile a path template to an anchored RegExp with named groups:\n * `:name` → one non-slash segment `*` → the rest (greedy)\n * A template with neither token is a literal exact match. Raw RegExp patterns\n * never reach here — they are the escape hatch, used as authored.\n */\nexport const compileTemplate = (template: string): RegExp => {\n const token = /(:[A-Za-z_][A-Za-z0-9_]*)|\\*/g;\n let src = '';\n let last = 0;\n let m: RegExpExecArray | null;\n while ((m = token.exec(template)) !== null) {\n src += escapeForRegexp(template.slice(last, m.index));\n src += m[1] ? `(?<${m[1].slice(1)}>[^/]+)` : `(?<${WILDCARD_GROUP}>.*)`;\n last = m.index + m[0].length;\n }\n src += escapeForRegexp(template.slice(last));\n return new RegExp(`^${src}$`);\n};\n\nconst templateCache = new Map<string, RegExp>();\n\n/** Resolve a pattern to a RegExp: templates are compiled (and cached), RegExp passes through. */\nexport const toRegExp = (pattern: string | RegExp): RegExp => {\n if (pattern instanceof RegExp) {\n return pattern;\n }\n let compiled = templateCache.get(pattern);\n if (!compiled) {\n compiled = compileTemplate(pattern);\n templateCache.set(pattern, compiled);\n }\n return compiled;\n};\n\n/**\n * Match a `sandboxPath` against a route pattern. Returns the named params on a\n * match (the `*` wildcard surfaces under the `'*'` key), or `null` otherwise.\n */\nexport const matchRoute = (pattern: string | RegExp, path: string): RouteParams | null => {\n const match = path.match(toRegExp(pattern));\n if (!match) {\n return null;\n }\n const params: RouteParams = {};\n for (const [key, value] of Object.entries(match.groups ?? {})) {\n if (value !== undefined) {\n params[key === WILDCARD_GROUP ? '*' : key] = value;\n }\n }\n return params;\n};\n"],"mappings":"AAGA,MAAM,kBAAkB,CAAC,QAAwB,IAAI,QAAQ,yBAAyB,MAAM;AAI5F,MAAM,iBAAiB;AAQhB,MAAM,kBAAkB,CAAC,aAA6B;AAC3D,QAAM,QAAQ;AACd,MAAI,MAAM;AACV,MAAI,OAAO;AACX,MAAI;AACJ,UAAQ,IAAI,MAAM,KAAK,QAAQ,OAAO,MAAM;AAC1C,WAAO,gBAAgB,SAAS,MAAM,MAAM,EAAE,KAAK,CAAC;AACpD,WAAO,EAAE,CAAC,IAAI,MAAM,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,YAAY,MAAM,cAAc;AACjE,WAAO,EAAE,QAAQ,EAAE,CAAC,EAAE;AAAA,EACxB;AACA,SAAO,gBAAgB,SAAS,MAAM,IAAI,CAAC;AAC3C,SAAO,IAAI,OAAO,IAAI,GAAG,GAAG;AAC9B;AAEA,MAAM,gBAAgB,oBAAI,IAAoB;AAGvC,MAAM,WAAW,CAAC,YAAqC;AAC5D,MAAI,mBAAmB,QAAQ;AAC7B,WAAO;AAAA,EACT;AACA,MAAI,WAAW,cAAc,IAAI,OAAO;AACxC,MAAI,CAAC,UAAU;AACb,eAAW,gBAAgB,OAAO;AAClC,kBAAc,IAAI,SAAS,QAAQ;AAAA,EACrC;AACA,SAAO;AACT;AAMO,MAAM,aAAa,CAAC,SAA0B,SAAqC;AACxF,QAAM,QAAQ,KAAK,MAAM,SAAS,OAAO,CAAC;AAC1C,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AACA,QAAM,SAAsB,CAAC;AAC7B,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,UAAU,CAAC,CAAC,GAAG;AAC7D,QAAI,UAAU,QAAW;AACvB,aAAO,QAAQ,iBAAiB,MAAM,GAAG,IAAI;AAAA,IAC/C;AAAA,EACF;AACA,SAAO;AACT;","names":[]}
package/dist/routing.cjs CHANGED
@@ -21,12 +21,17 @@ __export(routing_exports, {
21
21
  Router: () => Router,
22
22
  applyRoutingRule: () => applyRoutingRule,
23
23
  navigate: () => navigate,
24
+ renderRoute: () => renderRoute,
25
+ useRoute: () => useRoute,
26
+ useRouteParams: () => useRouteParams,
24
27
  useTinkerableLink: () => useTinkerableLink
25
28
  });
26
29
  module.exports = __toCommonJS(routing_exports);
30
+ var import_jsx_runtime = require("react/jsx-runtime");
27
31
  var import_react = require("react");
28
32
  var import_sandboxUtils = require("./sandboxUtils");
29
33
  var import_TinkerableContext = require("./TinkerableContext");
34
+ var import_routeMatch = require("./routeMatch");
30
35
  var import_urlUtils = require("./urlUtils");
31
36
  var import_pathUtils = require("./pathUtils");
32
37
  const useTinkerableLink = (newSandboxLocation) => {
@@ -42,29 +47,42 @@ const useTinkerableLink = (newSandboxLocation) => {
42
47
  const applyRoutingRule = (routingSpec, navigationState) => {
43
48
  const { sandboxPath } = navigationState;
44
49
  for (const routingRule of routingSpec.routes) {
45
- if (typeof routingRule.pattern === "string") {
46
- if (routingRule.pattern === sandboxPath) {
47
- return { routingRule };
48
- }
49
- } else {
50
- const match = sandboxPath.match(routingRule.pattern);
51
- if (routingRule.pattern.test(sandboxPath)) {
52
- return {
53
- routingRule,
54
- pathParameters: match?.groups
55
- };
56
- }
50
+ const pathParameters = (0, import_routeMatch.matchRoute)(routingRule.pattern, sandboxPath);
51
+ if (pathParameters) {
52
+ return { routingRule, pathParameters };
57
53
  }
58
54
  }
59
55
  return void 0;
60
56
  };
57
+ const renderRoute = (routingRule, params) => {
58
+ if (routingRule.component) {
59
+ const Component = routingRule.component;
60
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Component, { params });
61
+ }
62
+ return routingRule.element ?? routingRule.reactNode ?? null;
63
+ };
61
64
  const Router = () => {
62
65
  const context = (0, import_react.useContext)(import_TinkerableContext.TinkerableContext);
63
- const { navigationState: { routingRule } } = context;
66
+ const { navigationState: { routingRule, pathParameters } } = context;
64
67
  if (!routingRule) {
65
68
  throw new Error(`No route registered for path ${context.navigationState.sandboxPath}!`);
66
69
  }
67
- return routingRule.reactNode;
70
+ return renderRoute(routingRule, pathParameters ?? {});
71
+ };
72
+ const useRouteParams = () => (0, import_react.use)(import_TinkerableContext.TinkerableContext).navigationState.pathParameters ?? {};
73
+ const useRoute = () => {
74
+ const { navigationState } = (0, import_react.use)(import_TinkerableContext.TinkerableContext);
75
+ const { routingRule, pathParameters, sandboxPath, mode, provider, namespace, repository, ref } = navigationState;
76
+ return {
77
+ name: routingRule?.name,
78
+ params: pathParameters ?? {},
79
+ sandboxPath,
80
+ mode,
81
+ provider,
82
+ namespace,
83
+ repository,
84
+ ref
85
+ };
68
86
  };
69
87
  const navigate = (target) => {
70
88
  console.log(`[Sandbox] Navigating to ${target}`);
@@ -79,6 +97,9 @@ const navigate = (target) => {
79
97
  Router,
80
98
  applyRoutingRule,
81
99
  navigate,
100
+ renderRoute,
101
+ useRoute,
102
+ useRouteParams,
82
103
  useTinkerableLink
83
104
  });
84
105
  //# sourceMappingURL=routing.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/routing.tsx"],"sourcesContent":["import { use, useContext } from 'react';\n\nimport { sendMessage } from './sandboxUtils';\nimport { NavigationState, TinkerableContext } from './TinkerableContext';\nimport { RoutingRule, RoutingSpec } from './RoutingSpec';\nimport { constructUrl, isAbsolutePath, parseTarget } from './urlUtils';\nimport { joinPaths } from './pathUtils';\n\nexport type AppliedRoutingRule = {\n routingRule: RoutingRule,\n pathParameters?: Record<string, string>;\n}\n\nexport const useTinkerableLink = (newSandboxLocation: string) => {\n const { outerHref, navigationState: navigation } = use(TinkerableContext);\n let newNavigationState = parseTarget(newSandboxLocation, navigation);\n if (!isAbsolutePath(newSandboxLocation)) {\n newNavigationState.sandboxPath = joinPaths(navigation.sandboxPath, newSandboxLocation)\n } else {\n newNavigationState.sandboxPath = newSandboxLocation\n }\n return constructUrl(outerHref, newNavigationState);\n}\n\nexport const applyRoutingRule = (routingSpec:RoutingSpec, navigationState: NavigationState): AppliedRoutingRule | undefined => {\n const { sandboxPath } = navigationState;\n for (const routingRule of routingSpec.routes) {\n if (typeof routingRule.pattern === 'string') {\n if (routingRule.pattern === sandboxPath) {\n return {routingRule};\n }\n } else {\n const match = sandboxPath.match(routingRule.pattern);\n if (routingRule.pattern.test(sandboxPath)) {\n return {\n routingRule,\n pathParameters: match?.groups\n }\n }\n }\n }\n return undefined;\n}\n\nexport const Router = () => {\n const context = useContext(TinkerableContext);\n const {navigationState: {routingRule}} = context;\n if (!routingRule) {\n // TODO: better error\n throw new Error(`No route registered for path ${context.navigationState.sandboxPath}!`);\n }\n\n return routingRule.reactNode;\n};\n\n\n// Perform in-site navigation.\n// Top level frame is messaged to updated URL, after which a message will be\n// sent wit the new href, triggering the actual navigation.\nexport const navigate = (target: string) => {\n console.log(`[Sandbox] Navigating to ${target}`)\n sendMessage('urlchange', {\n url: target,\n back: false,\n forward: false,\n });\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAgC;AAEhC,0BAA4B;AAC5B,+BAAmD;AAEnD,sBAA0D;AAC1D,uBAA0B;AAOnB,MAAM,oBAAoB,CAAC,uBAA+B;AAC/D,QAAM,EAAE,WAAW,iBAAiB,WAAW,QAAI,kBAAI,0CAAiB;AACxE,MAAI,yBAAqB,6BAAY,oBAAoB,UAAU;AACnE,MAAI,KAAC,gCAAe,kBAAkB,GAAG;AACvC,uBAAmB,kBAAc,4BAAU,WAAW,aAAa,kBAAkB;AAAA,EACvF,OAAO;AACL,uBAAmB,cAAc;AAAA,EACnC;AACA,aAAO,8BAAa,WAAW,kBAAkB;AACnD;AAEO,MAAM,mBAAmB,CAAC,aAAyB,oBAAqE;AAC7H,QAAM,EAAE,YAAY,IAAI;AACxB,aAAW,eAAe,YAAY,QAAQ;AAC5C,QAAI,OAAO,YAAY,YAAY,UAAU;AAC3C,UAAI,YAAY,YAAY,aAAa;AACvC,eAAO,EAAC,YAAW;AAAA,MACrB;AAAA,IACF,OAAO;AACL,YAAM,QAAQ,YAAY,MAAM,YAAY,OAAO;AACnD,UAAI,YAAY,QAAQ,KAAK,WAAW,GAAG;AACzC,eAAO;AAAA,UACL;AAAA,UACA,gBAAgB,OAAO;AAAA,QACzB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEO,MAAM,SAAS,MAAM;AAC1B,QAAM,cAAU,yBAAW,0CAAiB;AAC5C,QAAM,EAAC,iBAAiB,EAAC,YAAW,EAAC,IAAI;AACzC,MAAI,CAAC,aAAa;AAEhB,UAAM,IAAI,MAAM,gCAAgC,QAAQ,gBAAgB,WAAW,GAAG;AAAA,EACxF;AAEA,SAAO,YAAY;AACrB;AAMO,MAAM,WAAW,CAAC,WAAmB;AAC1C,UAAQ,IAAI,2BAA2B,MAAM,EAAE;AAC/C,uCAAY,aAAa;AAAA,IACvB,KAAK;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA,EACX,CAAC;AACH;","names":[]}
1
+ {"version":3,"sources":["../src/routing.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport { use, useContext } from 'react';\n\nimport { sendMessage } from './sandboxUtils';\nimport { NavigationState, TinkerableContext } from './TinkerableContext';\nimport { RouteParams, RoutingRule, RoutingSpec } from './RoutingSpec';\nimport { matchRoute } from './routeMatch';\nimport { constructUrl, isAbsolutePath, parseTarget } from './urlUtils';\nimport { joinPaths } from './pathUtils';\n\n/** The result of matching a path: the winning {@link RoutingRule} plus its captured params. */\nexport type AppliedRoutingRule = {\n routingRule: RoutingRule,\n pathParameters?: Record<string, string>;\n}\n\n/** Build the full outer href for an in-app target (absolute `sandboxPath` or a\n * path relative to the current route), e.g. for an `href` attribute. */\nexport const useTinkerableLink = (newSandboxLocation: string) => {\n const { outerHref, navigationState: navigation } = use(TinkerableContext);\n let newNavigationState = parseTarget(newSandboxLocation, navigation);\n if (!isAbsolutePath(newSandboxLocation)) {\n newNavigationState.sandboxPath = joinPaths(navigation.sandboxPath, newSandboxLocation)\n } else {\n newNavigationState.sandboxPath = newSandboxLocation\n }\n return constructUrl(outerHref, newNavigationState);\n}\n\n/** Find the first rule in `routingSpec` whose pattern matches the current\n * `sandboxPath`, returning it with the captured params (or `undefined`). */\nexport const applyRoutingRule = (routingSpec:RoutingSpec, navigationState: NavigationState): AppliedRoutingRule | undefined => {\n const { sandboxPath } = navigationState;\n for (const routingRule of routingSpec.routes) {\n const pathParameters = matchRoute(routingRule.pattern, sandboxPath);\n if (pathParameters) {\n return { routingRule, pathParameters };\n }\n }\n return undefined;\n}\n\n/** Render a matched rule, passing params to a `component` and falling back to `element`/`reactNode`. */\nexport const renderRoute = (routingRule: RoutingRule, params: RouteParams): ReactNode => {\n if (routingRule.component) {\n const Component = routingRule.component;\n return <Component params={params} />;\n }\n return routingRule.element ?? routingRule.reactNode ?? null;\n};\n\n/** Render the route matched for the current location (set up by `boot`'s route table). */\nexport const Router = () => {\n const context = useContext(TinkerableContext);\n const {navigationState: {routingRule, pathParameters}} = context;\n if (!routingRule) {\n // TODO: better error\n throw new Error(`No route registered for path ${context.navigationState.sandboxPath}!`);\n }\n\n return renderRoute(routingRule, pathParameters ?? {});\n};\n\n/** Read the current route's matched params (`:name` segments and the `*` wildcard). */\nexport const useRouteParams = <T extends RouteParams = RouteParams>(): T =>\n (use(TinkerableContext).navigationState.pathParameters ?? {}) as T;\n\n/**\n * Read the current route: the matched rule's `name`, its `params`, the app-owned\n * `sandboxPath`, and the read-only platform prefix fields (`mode`, `provider`,\n * `namespace`, `repository`, `ref`) e.g. to tell `/edit` from `/present`.\n */\nexport const useRoute = () => {\n const { navigationState } = use(TinkerableContext);\n const { routingRule, pathParameters, sandboxPath, mode, provider, namespace, repository, ref } = navigationState;\n return {\n name: routingRule?.name,\n params: (pathParameters ?? {}) as RouteParams,\n sandboxPath,\n mode,\n provider,\n namespace,\n repository,\n ref,\n };\n};\n\n\n/**\n * Navigate within the app. Messages the host to update the URL; the host then\n * pushes the new href back, which drives the actual route change.\n */\nexport const navigate = (target: string) => {\n console.log(`[Sandbox] Navigating to ${target}`)\n sendMessage('urlchange', {\n url: target,\n back: false,\n forward: false,\n });\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA8CW;AA7CX,mBAAgC;AAEhC,0BAA4B;AAC5B,+BAAmD;AAEnD,wBAA2B;AAC3B,sBAA0D;AAC1D,uBAA0B;AAUnB,MAAM,oBAAoB,CAAC,uBAA+B;AAC/D,QAAM,EAAE,WAAW,iBAAiB,WAAW,QAAI,kBAAI,0CAAiB;AACxE,MAAI,yBAAqB,6BAAY,oBAAoB,UAAU;AACnE,MAAI,KAAC,gCAAe,kBAAkB,GAAG;AACvC,uBAAmB,kBAAc,4BAAU,WAAW,aAAa,kBAAkB;AAAA,EACvF,OAAO;AACL,uBAAmB,cAAc;AAAA,EACnC;AACA,aAAO,8BAAa,WAAW,kBAAkB;AACnD;AAIO,MAAM,mBAAmB,CAAC,aAAyB,oBAAqE;AAC7H,QAAM,EAAE,YAAY,IAAI;AACxB,aAAW,eAAe,YAAY,QAAQ;AAC5C,UAAM,qBAAiB,8BAAW,YAAY,SAAS,WAAW;AAClE,QAAI,gBAAgB;AAClB,aAAO,EAAE,aAAa,eAAe;AAAA,IACvC;AAAA,EACF;AACA,SAAO;AACT;AAGO,MAAM,cAAc,CAAC,aAA0B,WAAmC;AACvF,MAAI,YAAY,WAAW;AACzB,UAAM,YAAY,YAAY;AAC9B,WAAO,4CAAC,aAAU,QAAgB;AAAA,EACpC;AACA,SAAO,YAAY,WAAW,YAAY,aAAa;AACzD;AAGO,MAAM,SAAS,MAAM;AAC1B,QAAM,cAAU,yBAAW,0CAAiB;AAC5C,QAAM,EAAC,iBAAiB,EAAC,aAAa,eAAc,EAAC,IAAI;AACzD,MAAI,CAAC,aAAa;AAEhB,UAAM,IAAI,MAAM,gCAAgC,QAAQ,gBAAgB,WAAW,GAAG;AAAA,EACxF;AAEA,SAAO,YAAY,aAAa,kBAAkB,CAAC,CAAC;AACtD;AAGO,MAAM,iBAAiB,UAC3B,kBAAI,0CAAiB,EAAE,gBAAgB,kBAAkB,CAAC;AAOtD,MAAM,WAAW,MAAM;AAC5B,QAAM,EAAE,gBAAgB,QAAI,kBAAI,0CAAiB;AACjD,QAAM,EAAE,aAAa,gBAAgB,aAAa,MAAM,UAAU,WAAW,YAAY,IAAI,IAAI;AACjG,SAAO;AAAA,IACL,MAAM,aAAa;AAAA,IACnB,QAAS,kBAAkB,CAAC;AAAA,IAC5B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAOO,MAAM,WAAW,CAAC,WAAmB;AAC1C,UAAQ,IAAI,2BAA2B,MAAM,EAAE;AAC/C,uCAAY,aAAa;AAAA,IACvB,KAAK;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA,EACX,CAAC;AACH;","names":[]}
@@ -1,15 +1,44 @@
1
- import * as react from 'react';
1
+ import { ReactNode } from 'react';
2
2
  import { NavigationState } from './TinkerableContext.cjs';
3
- import { RoutingRule, RoutingSpec } from './RoutingSpec.cjs';
3
+ import { RoutingRule, RoutingSpec, RouteParams } from './RoutingSpec.cjs';
4
4
  import './sandboxTypes.cjs';
5
5
 
6
+ /** The result of matching a path: the winning {@link RoutingRule} plus its captured params. */
6
7
  type AppliedRoutingRule = {
7
8
  routingRule: RoutingRule;
8
9
  pathParameters?: Record<string, string>;
9
10
  };
11
+ /** Build the full outer href for an in-app target (absolute `sandboxPath` or a
12
+ * path relative to the current route), e.g. for an `href` attribute. */
10
13
  declare const useTinkerableLink: (newSandboxLocation: string) => string;
14
+ /** Find the first rule in `routingSpec` whose pattern matches the current
15
+ * `sandboxPath`, returning it with the captured params (or `undefined`). */
11
16
  declare const applyRoutingRule: (routingSpec: RoutingSpec, navigationState: NavigationState) => AppliedRoutingRule | undefined;
12
- declare const Router: () => react.ReactNode;
17
+ /** Render a matched rule, passing params to a `component` and falling back to `element`/`reactNode`. */
18
+ declare const renderRoute: (routingRule: RoutingRule, params: RouteParams) => ReactNode;
19
+ /** Render the route matched for the current location (set up by `boot`'s route table). */
20
+ declare const Router: () => ReactNode;
21
+ /** Read the current route's matched params (`:name` segments and the `*` wildcard). */
22
+ declare const useRouteParams: <T extends RouteParams = RouteParams>() => T;
23
+ /**
24
+ * Read the current route: the matched rule's `name`, its `params`, the app-owned
25
+ * `sandboxPath`, and the read-only platform prefix fields (`mode`, `provider`,
26
+ * `namespace`, `repository`, `ref`) — e.g. to tell `/edit` from `/present`.
27
+ */
28
+ declare const useRoute: () => {
29
+ name: string | undefined;
30
+ params: RouteParams;
31
+ sandboxPath: string;
32
+ mode: string;
33
+ provider: string;
34
+ namespace: string;
35
+ repository: string;
36
+ ref: string;
37
+ };
38
+ /**
39
+ * Navigate within the app. Messages the host to update the URL; the host then
40
+ * pushes the new href back, which drives the actual route change.
41
+ */
13
42
  declare const navigate: (target: string) => void;
14
43
 
15
- export { type AppliedRoutingRule, Router, applyRoutingRule, navigate, useTinkerableLink };
44
+ export { type AppliedRoutingRule, Router, applyRoutingRule, navigate, renderRoute, useRoute, useRouteParams, useTinkerableLink };
package/dist/routing.d.ts CHANGED
@@ -1,15 +1,44 @@
1
- import * as react from 'react';
1
+ import { ReactNode } from 'react';
2
2
  import { NavigationState } from './TinkerableContext.js';
3
- import { RoutingRule, RoutingSpec } from './RoutingSpec.js';
3
+ import { RoutingRule, RoutingSpec, RouteParams } from './RoutingSpec.js';
4
4
  import './sandboxTypes.js';
5
5
 
6
+ /** The result of matching a path: the winning {@link RoutingRule} plus its captured params. */
6
7
  type AppliedRoutingRule = {
7
8
  routingRule: RoutingRule;
8
9
  pathParameters?: Record<string, string>;
9
10
  };
11
+ /** Build the full outer href for an in-app target (absolute `sandboxPath` or a
12
+ * path relative to the current route), e.g. for an `href` attribute. */
10
13
  declare const useTinkerableLink: (newSandboxLocation: string) => string;
14
+ /** Find the first rule in `routingSpec` whose pattern matches the current
15
+ * `sandboxPath`, returning it with the captured params (or `undefined`). */
11
16
  declare const applyRoutingRule: (routingSpec: RoutingSpec, navigationState: NavigationState) => AppliedRoutingRule | undefined;
12
- declare const Router: () => react.ReactNode;
17
+ /** Render a matched rule, passing params to a `component` and falling back to `element`/`reactNode`. */
18
+ declare const renderRoute: (routingRule: RoutingRule, params: RouteParams) => ReactNode;
19
+ /** Render the route matched for the current location (set up by `boot`'s route table). */
20
+ declare const Router: () => ReactNode;
21
+ /** Read the current route's matched params (`:name` segments and the `*` wildcard). */
22
+ declare const useRouteParams: <T extends RouteParams = RouteParams>() => T;
23
+ /**
24
+ * Read the current route: the matched rule's `name`, its `params`, the app-owned
25
+ * `sandboxPath`, and the read-only platform prefix fields (`mode`, `provider`,
26
+ * `namespace`, `repository`, `ref`) — e.g. to tell `/edit` from `/present`.
27
+ */
28
+ declare const useRoute: () => {
29
+ name: string | undefined;
30
+ params: RouteParams;
31
+ sandboxPath: string;
32
+ mode: string;
33
+ provider: string;
34
+ namespace: string;
35
+ repository: string;
36
+ ref: string;
37
+ };
38
+ /**
39
+ * Navigate within the app. Messages the host to update the URL; the host then
40
+ * pushes the new href back, which drives the actual route change.
41
+ */
13
42
  declare const navigate: (target: string) => void;
14
43
 
15
- export { type AppliedRoutingRule, Router, applyRoutingRule, navigate, useTinkerableLink };
44
+ export { type AppliedRoutingRule, Router, applyRoutingRule, navigate, renderRoute, useRoute, useRouteParams, useTinkerableLink };
package/dist/routing.js CHANGED
@@ -1,6 +1,8 @@
1
+ import { jsx } from "react/jsx-runtime";
1
2
  import { use, useContext } from "react";
2
3
  import { sendMessage } from "./sandboxUtils";
3
4
  import { TinkerableContext } from "./TinkerableContext";
5
+ import { matchRoute } from "./routeMatch";
4
6
  import { constructUrl, isAbsolutePath, parseTarget } from "./urlUtils";
5
7
  import { joinPaths } from "./pathUtils";
6
8
  const useTinkerableLink = (newSandboxLocation) => {
@@ -16,29 +18,42 @@ const useTinkerableLink = (newSandboxLocation) => {
16
18
  const applyRoutingRule = (routingSpec, navigationState) => {
17
19
  const { sandboxPath } = navigationState;
18
20
  for (const routingRule of routingSpec.routes) {
19
- if (typeof routingRule.pattern === "string") {
20
- if (routingRule.pattern === sandboxPath) {
21
- return { routingRule };
22
- }
23
- } else {
24
- const match = sandboxPath.match(routingRule.pattern);
25
- if (routingRule.pattern.test(sandboxPath)) {
26
- return {
27
- routingRule,
28
- pathParameters: match?.groups
29
- };
30
- }
21
+ const pathParameters = matchRoute(routingRule.pattern, sandboxPath);
22
+ if (pathParameters) {
23
+ return { routingRule, pathParameters };
31
24
  }
32
25
  }
33
26
  return void 0;
34
27
  };
28
+ const renderRoute = (routingRule, params) => {
29
+ if (routingRule.component) {
30
+ const Component = routingRule.component;
31
+ return /* @__PURE__ */ jsx(Component, { params });
32
+ }
33
+ return routingRule.element ?? routingRule.reactNode ?? null;
34
+ };
35
35
  const Router = () => {
36
36
  const context = useContext(TinkerableContext);
37
- const { navigationState: { routingRule } } = context;
37
+ const { navigationState: { routingRule, pathParameters } } = context;
38
38
  if (!routingRule) {
39
39
  throw new Error(`No route registered for path ${context.navigationState.sandboxPath}!`);
40
40
  }
41
- return routingRule.reactNode;
41
+ return renderRoute(routingRule, pathParameters ?? {});
42
+ };
43
+ const useRouteParams = () => use(TinkerableContext).navigationState.pathParameters ?? {};
44
+ const useRoute = () => {
45
+ const { navigationState } = use(TinkerableContext);
46
+ const { routingRule, pathParameters, sandboxPath, mode, provider, namespace, repository, ref } = navigationState;
47
+ return {
48
+ name: routingRule?.name,
49
+ params: pathParameters ?? {},
50
+ sandboxPath,
51
+ mode,
52
+ provider,
53
+ namespace,
54
+ repository,
55
+ ref
56
+ };
42
57
  };
43
58
  const navigate = (target) => {
44
59
  console.log(`[Sandbox] Navigating to ${target}`);
@@ -52,6 +67,9 @@ export {
52
67
  Router,
53
68
  applyRoutingRule,
54
69
  navigate,
70
+ renderRoute,
71
+ useRoute,
72
+ useRouteParams,
55
73
  useTinkerableLink
56
74
  };
57
75
  //# sourceMappingURL=routing.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/routing.tsx"],"sourcesContent":["import { use, useContext } from 'react';\n\nimport { sendMessage } from './sandboxUtils';\nimport { NavigationState, TinkerableContext } from './TinkerableContext';\nimport { RoutingRule, RoutingSpec } from './RoutingSpec';\nimport { constructUrl, isAbsolutePath, parseTarget } from './urlUtils';\nimport { joinPaths } from './pathUtils';\n\nexport type AppliedRoutingRule = {\n routingRule: RoutingRule,\n pathParameters?: Record<string, string>;\n}\n\nexport const useTinkerableLink = (newSandboxLocation: string) => {\n const { outerHref, navigationState: navigation } = use(TinkerableContext);\n let newNavigationState = parseTarget(newSandboxLocation, navigation);\n if (!isAbsolutePath(newSandboxLocation)) {\n newNavigationState.sandboxPath = joinPaths(navigation.sandboxPath, newSandboxLocation)\n } else {\n newNavigationState.sandboxPath = newSandboxLocation\n }\n return constructUrl(outerHref, newNavigationState);\n}\n\nexport const applyRoutingRule = (routingSpec:RoutingSpec, navigationState: NavigationState): AppliedRoutingRule | undefined => {\n const { sandboxPath } = navigationState;\n for (const routingRule of routingSpec.routes) {\n if (typeof routingRule.pattern === 'string') {\n if (routingRule.pattern === sandboxPath) {\n return {routingRule};\n }\n } else {\n const match = sandboxPath.match(routingRule.pattern);\n if (routingRule.pattern.test(sandboxPath)) {\n return {\n routingRule,\n pathParameters: match?.groups\n }\n }\n }\n }\n return undefined;\n}\n\nexport const Router = () => {\n const context = useContext(TinkerableContext);\n const {navigationState: {routingRule}} = context;\n if (!routingRule) {\n // TODO: better error\n throw new Error(`No route registered for path ${context.navigationState.sandboxPath}!`);\n }\n\n return routingRule.reactNode;\n};\n\n\n// Perform in-site navigation.\n// Top level frame is messaged to updated URL, after which a message will be\n// sent wit the new href, triggering the actual navigation.\nexport const navigate = (target: string) => {\n console.log(`[Sandbox] Navigating to ${target}`)\n sendMessage('urlchange', {\n url: target,\n back: false,\n forward: false,\n });\n};\n"],"mappings":"AAAA,SAAS,KAAK,kBAAkB;AAEhC,SAAS,mBAAmB;AAC5B,SAA0B,yBAAyB;AAEnD,SAAS,cAAc,gBAAgB,mBAAmB;AAC1D,SAAS,iBAAiB;AAOnB,MAAM,oBAAoB,CAAC,uBAA+B;AAC/D,QAAM,EAAE,WAAW,iBAAiB,WAAW,IAAI,IAAI,iBAAiB;AACxE,MAAI,qBAAqB,YAAY,oBAAoB,UAAU;AACnE,MAAI,CAAC,eAAe,kBAAkB,GAAG;AACvC,uBAAmB,cAAc,UAAU,WAAW,aAAa,kBAAkB;AAAA,EACvF,OAAO;AACL,uBAAmB,cAAc;AAAA,EACnC;AACA,SAAO,aAAa,WAAW,kBAAkB;AACnD;AAEO,MAAM,mBAAmB,CAAC,aAAyB,oBAAqE;AAC7H,QAAM,EAAE,YAAY,IAAI;AACxB,aAAW,eAAe,YAAY,QAAQ;AAC5C,QAAI,OAAO,YAAY,YAAY,UAAU;AAC3C,UAAI,YAAY,YAAY,aAAa;AACvC,eAAO,EAAC,YAAW;AAAA,MACrB;AAAA,IACF,OAAO;AACL,YAAM,QAAQ,YAAY,MAAM,YAAY,OAAO;AACnD,UAAI,YAAY,QAAQ,KAAK,WAAW,GAAG;AACzC,eAAO;AAAA,UACL;AAAA,UACA,gBAAgB,OAAO;AAAA,QACzB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEO,MAAM,SAAS,MAAM;AAC1B,QAAM,UAAU,WAAW,iBAAiB;AAC5C,QAAM,EAAC,iBAAiB,EAAC,YAAW,EAAC,IAAI;AACzC,MAAI,CAAC,aAAa;AAEhB,UAAM,IAAI,MAAM,gCAAgC,QAAQ,gBAAgB,WAAW,GAAG;AAAA,EACxF;AAEA,SAAO,YAAY;AACrB;AAMO,MAAM,WAAW,CAAC,WAAmB;AAC1C,UAAQ,IAAI,2BAA2B,MAAM,EAAE;AAC/C,cAAY,aAAa;AAAA,IACvB,KAAK;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA,EACX,CAAC;AACH;","names":[]}
1
+ {"version":3,"sources":["../src/routing.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport { use, useContext } from 'react';\n\nimport { sendMessage } from './sandboxUtils';\nimport { NavigationState, TinkerableContext } from './TinkerableContext';\nimport { RouteParams, RoutingRule, RoutingSpec } from './RoutingSpec';\nimport { matchRoute } from './routeMatch';\nimport { constructUrl, isAbsolutePath, parseTarget } from './urlUtils';\nimport { joinPaths } from './pathUtils';\n\n/** The result of matching a path: the winning {@link RoutingRule} plus its captured params. */\nexport type AppliedRoutingRule = {\n routingRule: RoutingRule,\n pathParameters?: Record<string, string>;\n}\n\n/** Build the full outer href for an in-app target (absolute `sandboxPath` or a\n * path relative to the current route), e.g. for an `href` attribute. */\nexport const useTinkerableLink = (newSandboxLocation: string) => {\n const { outerHref, navigationState: navigation } = use(TinkerableContext);\n let newNavigationState = parseTarget(newSandboxLocation, navigation);\n if (!isAbsolutePath(newSandboxLocation)) {\n newNavigationState.sandboxPath = joinPaths(navigation.sandboxPath, newSandboxLocation)\n } else {\n newNavigationState.sandboxPath = newSandboxLocation\n }\n return constructUrl(outerHref, newNavigationState);\n}\n\n/** Find the first rule in `routingSpec` whose pattern matches the current\n * `sandboxPath`, returning it with the captured params (or `undefined`). */\nexport const applyRoutingRule = (routingSpec:RoutingSpec, navigationState: NavigationState): AppliedRoutingRule | undefined => {\n const { sandboxPath } = navigationState;\n for (const routingRule of routingSpec.routes) {\n const pathParameters = matchRoute(routingRule.pattern, sandboxPath);\n if (pathParameters) {\n return { routingRule, pathParameters };\n }\n }\n return undefined;\n}\n\n/** Render a matched rule, passing params to a `component` and falling back to `element`/`reactNode`. */\nexport const renderRoute = (routingRule: RoutingRule, params: RouteParams): ReactNode => {\n if (routingRule.component) {\n const Component = routingRule.component;\n return <Component params={params} />;\n }\n return routingRule.element ?? routingRule.reactNode ?? null;\n};\n\n/** Render the route matched for the current location (set up by `boot`'s route table). */\nexport const Router = () => {\n const context = useContext(TinkerableContext);\n const {navigationState: {routingRule, pathParameters}} = context;\n if (!routingRule) {\n // TODO: better error\n throw new Error(`No route registered for path ${context.navigationState.sandboxPath}!`);\n }\n\n return renderRoute(routingRule, pathParameters ?? {});\n};\n\n/** Read the current route's matched params (`:name` segments and the `*` wildcard). */\nexport const useRouteParams = <T extends RouteParams = RouteParams>(): T =>\n (use(TinkerableContext).navigationState.pathParameters ?? {}) as T;\n\n/**\n * Read the current route: the matched rule's `name`, its `params`, the app-owned\n * `sandboxPath`, and the read-only platform prefix fields (`mode`, `provider`,\n * `namespace`, `repository`, `ref`) e.g. to tell `/edit` from `/present`.\n */\nexport const useRoute = () => {\n const { navigationState } = use(TinkerableContext);\n const { routingRule, pathParameters, sandboxPath, mode, provider, namespace, repository, ref } = navigationState;\n return {\n name: routingRule?.name,\n params: (pathParameters ?? {}) as RouteParams,\n sandboxPath,\n mode,\n provider,\n namespace,\n repository,\n ref,\n };\n};\n\n\n/**\n * Navigate within the app. Messages the host to update the URL; the host then\n * pushes the new href back, which drives the actual route change.\n */\nexport const navigate = (target: string) => {\n console.log(`[Sandbox] Navigating to ${target}`)\n sendMessage('urlchange', {\n url: target,\n back: false,\n forward: false,\n });\n};\n"],"mappings":"AA8CW;AA7CX,SAAS,KAAK,kBAAkB;AAEhC,SAAS,mBAAmB;AAC5B,SAA0B,yBAAyB;AAEnD,SAAS,kBAAkB;AAC3B,SAAS,cAAc,gBAAgB,mBAAmB;AAC1D,SAAS,iBAAiB;AAUnB,MAAM,oBAAoB,CAAC,uBAA+B;AAC/D,QAAM,EAAE,WAAW,iBAAiB,WAAW,IAAI,IAAI,iBAAiB;AACxE,MAAI,qBAAqB,YAAY,oBAAoB,UAAU;AACnE,MAAI,CAAC,eAAe,kBAAkB,GAAG;AACvC,uBAAmB,cAAc,UAAU,WAAW,aAAa,kBAAkB;AAAA,EACvF,OAAO;AACL,uBAAmB,cAAc;AAAA,EACnC;AACA,SAAO,aAAa,WAAW,kBAAkB;AACnD;AAIO,MAAM,mBAAmB,CAAC,aAAyB,oBAAqE;AAC7H,QAAM,EAAE,YAAY,IAAI;AACxB,aAAW,eAAe,YAAY,QAAQ;AAC5C,UAAM,iBAAiB,WAAW,YAAY,SAAS,WAAW;AAClE,QAAI,gBAAgB;AAClB,aAAO,EAAE,aAAa,eAAe;AAAA,IACvC;AAAA,EACF;AACA,SAAO;AACT;AAGO,MAAM,cAAc,CAAC,aAA0B,WAAmC;AACvF,MAAI,YAAY,WAAW;AACzB,UAAM,YAAY,YAAY;AAC9B,WAAO,oBAAC,aAAU,QAAgB;AAAA,EACpC;AACA,SAAO,YAAY,WAAW,YAAY,aAAa;AACzD;AAGO,MAAM,SAAS,MAAM;AAC1B,QAAM,UAAU,WAAW,iBAAiB;AAC5C,QAAM,EAAC,iBAAiB,EAAC,aAAa,eAAc,EAAC,IAAI;AACzD,MAAI,CAAC,aAAa;AAEhB,UAAM,IAAI,MAAM,gCAAgC,QAAQ,gBAAgB,WAAW,GAAG;AAAA,EACxF;AAEA,SAAO,YAAY,aAAa,kBAAkB,CAAC,CAAC;AACtD;AAGO,MAAM,iBAAiB,MAC3B,IAAI,iBAAiB,EAAE,gBAAgB,kBAAkB,CAAC;AAOtD,MAAM,WAAW,MAAM;AAC5B,QAAM,EAAE,gBAAgB,IAAI,IAAI,iBAAiB;AACjD,QAAM,EAAE,aAAa,gBAAgB,aAAa,MAAM,UAAU,WAAW,YAAY,IAAI,IAAI;AACjG,SAAO;AAAA,IACL,MAAM,aAAa;AAAA,IACnB,QAAS,kBAAkB,CAAC;AAAA,IAC5B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAOO,MAAM,WAAW,CAAC,WAAmB;AAC1C,UAAQ,IAAI,2BAA2B,MAAM,EAAE;AAC/C,cAAY,aAAa;AAAA,IACvB,KAAK;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA,EACX,CAAC;AACH;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/runtime.ts"],"sourcesContent":["// Runtime discovery + version handshake (SDK_PACKAGING_SPEC §4/§6).\n//\n// Today the SDK reaches the host through the INJECTED sandbox services\n// (`module.evaluation.module.bundler.*`, see sandboxUtils). The packaging migration\n// makes the SDK an app-pinnable npm dependency that finds the runtime through a\n// stable, versioned global the sandbox publishes BEFORE evaluating app code:\n//\n// globalThis.__immediatelyRun__ = { runtimeVersion, protocolVersion, transport }\n//\n// Phase 1 (behind a flag, injection still active): the SDK can READ that global\n// when present (else fall back to injection), and ANNOUNCE its own version +\n// protocol so the host can record + version-check it (§6/T45). The transport itself\n// is unchanged here — this only wires the discovery + handshake fields so the check\n// exists when app-pinned versions become real.\nimport { sendMessage, addListener } from './sandboxUtils';\nimport { SDK_VERSION } from './version';\n\n// `getHostRuntime` + `ImmediatelyRunGlobal` live in the leaf `hostRuntime` module\n// (imports nothing) and are re-exported here for a stable public API. This breaks\n// the sandboxUtils↔runtime import cycle: sandboxUtils reads `getHostRuntime` from\n// the leaf, while runtime still imports sandboxUtils for the handshake — one\n// direction only, no cycle.\nexport { getHostRuntime } from './hostRuntime';\nexport type { ImmediatelyRunGlobal } from './hostRuntime';\n\n/** The wire protocol (postMessage envelope / channels / methods) THIS SDK speaks.\n * Additive-only (§9); bump only for a backwards-compatible extension. */\nexport const SDK_PROTOCOL_VERSION = '1.0.0';\n\n/** This SDK's package version, baked from package.json at build (SP2-6,\n * `scripts/gen-version.mjs`). Re-exported so the public surface is unchanged\n * (`@immediately-run/sdk` → `SDK_VERSION`); imported above for the handshake. */\nexport { SDK_VERSION };\n\n/** This SDK's handshake payload — the version + protocol the host records + checks\n * against `HOST_PROTOCOL_VERSION` (§6/T45). */\nexport interface SdkHandshake {\n sdkVersion: string;\n protocolVersion: string;\n}\nexport const sdkHandshake = (): SdkHandshake => ({\n sdkVersion: SDK_VERSION,\n protocolVersion: SDK_PROTOCOL_VERSION,\n});\n\n/**\n * Announce this SDK's version to the host (§6). Sends `sdk-handshake` eagerly\n * (best-effort — the host may already be listening) AND replies to a host\n * `request-handshake` (the robust path, mirroring the other `request-*` pulls).\n * Idempotent; safe to call more than once. Returns an unsubscribe fn.\n */\nexport function announceHandshake(): () => void {\n const send = () => {\n try {\n sendMessage('sdk-handshake', sdkHandshake() as unknown as Record<string, unknown>);\n } catch {\n /* transport not ready yet — the request-handshake reply covers it */\n }\n };\n send();\n return addListener('request-handshake', send);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAcA,0BAAyC;AACzC,qBAA4B;AAO5B,yBAA+B;AAKxB,MAAM,uBAAuB;AAa7B,MAAM,eAAe,OAAqB;AAAA,EAC/C,YAAY;AAAA,EACZ,iBAAiB;AACnB;AAQO,SAAS,oBAAgC;AAC9C,QAAM,OAAO,MAAM;AACjB,QAAI;AACF,2CAAY,iBAAiB,aAAa,CAAuC;AAAA,IACnF,QAAQ;AAAA,IAER;AAAA,EACF;AACA,OAAK;AACL,aAAO,iCAAY,qBAAqB,IAAI;AAC9C;","names":[]}
1
+ {"version":3,"sources":["../src/runtime.ts"],"sourcesContent":["// Runtime discovery + version handshake (SDK_PACKAGING_SPEC §4/§6).\n//\n// Today the SDK reaches the host through the INJECTED sandbox services\n// (`module.evaluation.module.bundler.*`, see sandboxUtils). The packaging migration\n// makes the SDK an app-pinnable npm dependency that finds the runtime through a\n// stable, versioned global the sandbox publishes BEFORE evaluating app code:\n//\n// globalThis.__immediatelyRun__ = { runtimeVersion, protocolVersion, transport }\n//\n// Phase 1 (behind a flag, injection still active): the SDK can READ that global\n// when present (else fall back to injection), and ANNOUNCE its own version +\n// protocol so the host can record + version-check it (§6/T45). The transport itself\n// is unchanged here — this only wires the discovery + handshake fields so the check\n// exists when app-pinned versions become real.\nimport { sendMessage, addListener } from './sandboxUtils';\nimport { SDK_VERSION } from './version';\n\n// `getHostRuntime` + `ImmediatelyRunGlobal` live in the leaf `hostRuntime` module\n// (imports nothing) and are re-exported here for a stable public API. This breaks\n// the sandboxUtils↔runtime import cycle: sandboxUtils reads `getHostRuntime` from\n// the leaf, while runtime still imports sandboxUtils for the handshake — one\n// direction only, no cycle.\nexport { getHostRuntime } from './hostRuntime';\nexport type { ImmediatelyRunGlobal } from './hostRuntime';\n\n/** The wire protocol (postMessage envelope / channels / methods) THIS SDK speaks.\n * Additive-only (§9); bump only for a backwards-compatible extension. */\nexport const SDK_PROTOCOL_VERSION = '1.0.0';\n\n/** This SDK's package version, baked from package.json at build (SP2-6,\n * `scripts/gen-version.mjs`). Re-exported so the public surface is unchanged\n * (`@immediately-run/sdk` → `SDK_VERSION`); imported above for the handshake. */\nexport { SDK_VERSION };\n\n/** This SDK's handshake payload — the version + protocol the host records + checks\n * against `HOST_PROTOCOL_VERSION` (§6/T45). */\nexport interface SdkHandshake {\n sdkVersion: string;\n protocolVersion: string;\n}\n/** Build this SDK's handshake payload (version + protocol) for the host to record. */\nexport const sdkHandshake = (): SdkHandshake => ({\n sdkVersion: SDK_VERSION,\n protocolVersion: SDK_PROTOCOL_VERSION,\n});\n\n/**\n * Announce this SDK's version to the host (§6). Sends `sdk-handshake` eagerly\n * (best-effort — the host may already be listening) AND replies to a host\n * `request-handshake` (the robust path, mirroring the other `request-*` pulls).\n * Idempotent; safe to call more than once. Returns an unsubscribe fn.\n */\nexport function announceHandshake(): () => void {\n const send = () => {\n try {\n sendMessage('sdk-handshake', sdkHandshake() as unknown as Record<string, unknown>);\n } catch {\n /* transport not ready yet — the request-handshake reply covers it */\n }\n };\n send();\n return addListener('request-handshake', send);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAcA,0BAAyC;AACzC,qBAA4B;AAO5B,yBAA+B;AAKxB,MAAM,uBAAuB;AAc7B,MAAM,eAAe,OAAqB;AAAA,EAC/C,YAAY;AAAA,EACZ,iBAAiB;AACnB;AAQO,SAAS,oBAAgC;AAC9C,QAAM,OAAO,MAAM;AACjB,QAAI;AACF,2CAAY,iBAAiB,aAAa,CAAuC;AAAA,IACnF,QAAQ;AAAA,IAER;AAAA,EACF;AACA,OAAK;AACL,aAAO,iCAAY,qBAAqB,IAAI;AAC9C;","names":[]}
@@ -11,6 +11,7 @@ interface SdkHandshake {
11
11
  sdkVersion: string;
12
12
  protocolVersion: string;
13
13
  }
14
+ /** Build this SDK's handshake payload (version + protocol) for the host to record. */
14
15
  declare const sdkHandshake: () => SdkHandshake;
15
16
  /**
16
17
  * Announce this SDK's version to the host (§6). Sends `sdk-handshake` eagerly
package/dist/runtime.d.ts CHANGED
@@ -11,6 +11,7 @@ interface SdkHandshake {
11
11
  sdkVersion: string;
12
12
  protocolVersion: string;
13
13
  }
14
+ /** Build this SDK's handshake payload (version + protocol) for the host to record. */
14
15
  declare const sdkHandshake: () => SdkHandshake;
15
16
  /**
16
17
  * Announce this SDK's version to the host (§6). Sends `sdk-handshake` eagerly
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/runtime.ts"],"sourcesContent":["// Runtime discovery + version handshake (SDK_PACKAGING_SPEC §4/§6).\n//\n// Today the SDK reaches the host through the INJECTED sandbox services\n// (`module.evaluation.module.bundler.*`, see sandboxUtils). The packaging migration\n// makes the SDK an app-pinnable npm dependency that finds the runtime through a\n// stable, versioned global the sandbox publishes BEFORE evaluating app code:\n//\n// globalThis.__immediatelyRun__ = { runtimeVersion, protocolVersion, transport }\n//\n// Phase 1 (behind a flag, injection still active): the SDK can READ that global\n// when present (else fall back to injection), and ANNOUNCE its own version +\n// protocol so the host can record + version-check it (§6/T45). The transport itself\n// is unchanged here — this only wires the discovery + handshake fields so the check\n// exists when app-pinned versions become real.\nimport { sendMessage, addListener } from './sandboxUtils';\nimport { SDK_VERSION } from './version';\n\n// `getHostRuntime` + `ImmediatelyRunGlobal` live in the leaf `hostRuntime` module\n// (imports nothing) and are re-exported here for a stable public API. This breaks\n// the sandboxUtils↔runtime import cycle: sandboxUtils reads `getHostRuntime` from\n// the leaf, while runtime still imports sandboxUtils for the handshake — one\n// direction only, no cycle.\nexport { getHostRuntime } from './hostRuntime';\nexport type { ImmediatelyRunGlobal } from './hostRuntime';\n\n/** The wire protocol (postMessage envelope / channels / methods) THIS SDK speaks.\n * Additive-only (§9); bump only for a backwards-compatible extension. */\nexport const SDK_PROTOCOL_VERSION = '1.0.0';\n\n/** This SDK's package version, baked from package.json at build (SP2-6,\n * `scripts/gen-version.mjs`). Re-exported so the public surface is unchanged\n * (`@immediately-run/sdk` → `SDK_VERSION`); imported above for the handshake. */\nexport { SDK_VERSION };\n\n/** This SDK's handshake payload — the version + protocol the host records + checks\n * against `HOST_PROTOCOL_VERSION` (§6/T45). */\nexport interface SdkHandshake {\n sdkVersion: string;\n protocolVersion: string;\n}\nexport const sdkHandshake = (): SdkHandshake => ({\n sdkVersion: SDK_VERSION,\n protocolVersion: SDK_PROTOCOL_VERSION,\n});\n\n/**\n * Announce this SDK's version to the host (§6). Sends `sdk-handshake` eagerly\n * (best-effort — the host may already be listening) AND replies to a host\n * `request-handshake` (the robust path, mirroring the other `request-*` pulls).\n * Idempotent; safe to call more than once. Returns an unsubscribe fn.\n */\nexport function announceHandshake(): () => void {\n const send = () => {\n try {\n sendMessage('sdk-handshake', sdkHandshake() as unknown as Record<string, unknown>);\n } catch {\n /* transport not ready yet — the request-handshake reply covers it */\n }\n };\n send();\n return addListener('request-handshake', send);\n}\n"],"mappings":"AAcA,SAAS,aAAa,mBAAmB;AACzC,SAAS,mBAAmB;AAO5B,SAAS,sBAAsB;AAKxB,MAAM,uBAAuB;AAa7B,MAAM,eAAe,OAAqB;AAAA,EAC/C,YAAY;AAAA,EACZ,iBAAiB;AACnB;AAQO,SAAS,oBAAgC;AAC9C,QAAM,OAAO,MAAM;AACjB,QAAI;AACF,kBAAY,iBAAiB,aAAa,CAAuC;AAAA,IACnF,QAAQ;AAAA,IAER;AAAA,EACF;AACA,OAAK;AACL,SAAO,YAAY,qBAAqB,IAAI;AAC9C;","names":[]}
1
+ {"version":3,"sources":["../src/runtime.ts"],"sourcesContent":["// Runtime discovery + version handshake (SDK_PACKAGING_SPEC §4/§6).\n//\n// Today the SDK reaches the host through the INJECTED sandbox services\n// (`module.evaluation.module.bundler.*`, see sandboxUtils). The packaging migration\n// makes the SDK an app-pinnable npm dependency that finds the runtime through a\n// stable, versioned global the sandbox publishes BEFORE evaluating app code:\n//\n// globalThis.__immediatelyRun__ = { runtimeVersion, protocolVersion, transport }\n//\n// Phase 1 (behind a flag, injection still active): the SDK can READ that global\n// when present (else fall back to injection), and ANNOUNCE its own version +\n// protocol so the host can record + version-check it (§6/T45). The transport itself\n// is unchanged here — this only wires the discovery + handshake fields so the check\n// exists when app-pinned versions become real.\nimport { sendMessage, addListener } from './sandboxUtils';\nimport { SDK_VERSION } from './version';\n\n// `getHostRuntime` + `ImmediatelyRunGlobal` live in the leaf `hostRuntime` module\n// (imports nothing) and are re-exported here for a stable public API. This breaks\n// the sandboxUtils↔runtime import cycle: sandboxUtils reads `getHostRuntime` from\n// the leaf, while runtime still imports sandboxUtils for the handshake — one\n// direction only, no cycle.\nexport { getHostRuntime } from './hostRuntime';\nexport type { ImmediatelyRunGlobal } from './hostRuntime';\n\n/** The wire protocol (postMessage envelope / channels / methods) THIS SDK speaks.\n * Additive-only (§9); bump only for a backwards-compatible extension. */\nexport const SDK_PROTOCOL_VERSION = '1.0.0';\n\n/** This SDK's package version, baked from package.json at build (SP2-6,\n * `scripts/gen-version.mjs`). Re-exported so the public surface is unchanged\n * (`@immediately-run/sdk` → `SDK_VERSION`); imported above for the handshake. */\nexport { SDK_VERSION };\n\n/** This SDK's handshake payload — the version + protocol the host records + checks\n * against `HOST_PROTOCOL_VERSION` (§6/T45). */\nexport interface SdkHandshake {\n sdkVersion: string;\n protocolVersion: string;\n}\n/** Build this SDK's handshake payload (version + protocol) for the host to record. */\nexport const sdkHandshake = (): SdkHandshake => ({\n sdkVersion: SDK_VERSION,\n protocolVersion: SDK_PROTOCOL_VERSION,\n});\n\n/**\n * Announce this SDK's version to the host (§6). Sends `sdk-handshake` eagerly\n * (best-effort — the host may already be listening) AND replies to a host\n * `request-handshake` (the robust path, mirroring the other `request-*` pulls).\n * Idempotent; safe to call more than once. Returns an unsubscribe fn.\n */\nexport function announceHandshake(): () => void {\n const send = () => {\n try {\n sendMessage('sdk-handshake', sdkHandshake() as unknown as Record<string, unknown>);\n } catch {\n /* transport not ready yet — the request-handshake reply covers it */\n }\n };\n send();\n return addListener('request-handshake', send);\n}\n"],"mappings":"AAcA,SAAS,aAAa,mBAAmB;AACzC,SAAS,mBAAmB;AAO5B,SAAS,sBAAsB;AAKxB,MAAM,uBAAuB;AAc7B,MAAM,eAAe,OAAqB;AAAA,EAC/C,YAAY;AAAA,EACZ,iBAAiB;AACnB;AAQO,SAAS,oBAAgC;AAC9C,QAAM,OAAO,MAAM;AACjB,QAAI;AACF,kBAAY,iBAAiB,aAAa,CAAuC;AAAA,IACnF,QAAQ;AAAA,IAER;AAAA,EACF;AACA,OAAK;AACL,SAAO,YAAY,qBAAqB,IAAI;AAC9C;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/sandboxTypes.ts"],"sourcesContent":["export type ModuleExports = any\n\n// The real type is EvaluationContext from src/bundler/module/Evaluation.ts:6\nexport type EvaluationContext = {\n exports: ModuleExports;\n dynamicImport: (moduleToImport: string, symbolToImport:string) => Promise<ModuleExports>;\n getModuleEvaluationContext: (moduleName: string) => Promise<EvaluationContext>;\n resolve: (moduleName: string) => Promise<string>;\n evaluation: {\n module: {\n source: string;\n filepath: string;\n }\n }\n}\n\nexport type Metadata = Record<string, any>;\nexport type FilesMetadata = Record<string, Metadata>;\nexport type FileQueryResult = string[]\nexport type MetadataQueryFunction = (filesMetadata:FilesMetadata) => FileQueryResult;\nexport type MetadataQueryResult = {result: FileQueryResult} | {error: any}\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
1
+ {"version":3,"sources":["../src/sandboxTypes.ts"],"sourcesContent":["/** The exports object of an evaluated sandbox module (untyped — shape depends on the module). */\nexport type ModuleExports = any\n\n/** The sandbox runtime's per-module evaluation context: a module's exports plus the\n * helpers to dynamically import, resolve, and re-evaluate other modules.\n * (The real type is `EvaluationContext` from `src/bundler/module/Evaluation.ts`.) */\nexport type EvaluationContext = {\n exports: ModuleExports;\n dynamicImport: (moduleToImport: string, symbolToImport:string) => Promise<ModuleExports>;\n getModuleEvaluationContext: (moduleName: string) => Promise<EvaluationContext>;\n resolve: (moduleName: string) => Promise<string>;\n evaluation: {\n module: {\n source: string;\n filepath: string;\n }\n }\n}\n\n/**\n * The parsed frontmatter of a single file. Apps can supply their own shape as the\n * `T` type parameter on the metadata hooks for typed field access; it defaults to\n * an open record.\n */\nexport type Metadata = Record<string, any>;\n\n/** The whole metadata store: a map from repo-relative file path to its frontmatter. */\nexport type FilesMetadata<T = Metadata> = Record<string, T>;\n\n/** The paths a {@link MetadataQueryFunction} selected. */\nexport type FileQueryResult = string[]\n\n/**\n * A query over the metadata store: receive every file's frontmatter keyed by path\n * and return the paths that match. Plain JS — `Object.entries(...).filter(...)` —\n * no query language to learn.\n */\nexport type MetadataQueryFunction<T = Metadata> = (filesMetadata: FilesMetadata<T>) => FileQueryResult;\n\n/** One match from {@link MetadataQueryFunction}: the file path paired with its frontmatter. */\nexport type MetadataQueryEntry<T = Metadata> = { path: string; meta: T };\n\n/**\n * The result of running a metadata query: the matched entries (path + frontmatter),\n * or the error a throwing query produced.\n */\nexport type MetadataQueryResult<T = Metadata> = MetadataQueryEntry<T>[] | { error: unknown }\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
@@ -1,4 +1,8 @@
1
+ /** The exports object of an evaluated sandbox module (untyped — shape depends on the module). */
1
2
  type ModuleExports = any;
3
+ /** The sandbox runtime's per-module evaluation context: a module's exports plus the
4
+ * helpers to dynamically import, resolve, and re-evaluate other modules.
5
+ * (The real type is `EvaluationContext` from `src/bundler/module/Evaluation.ts`.) */
2
6
  type EvaluationContext = {
3
7
  exports: ModuleExports;
4
8
  dynamicImport: (moduleToImport: string, symbolToImport: string) => Promise<ModuleExports>;
@@ -11,14 +15,33 @@ type EvaluationContext = {
11
15
  };
12
16
  };
13
17
  };
18
+ /**
19
+ * The parsed frontmatter of a single file. Apps can supply their own shape as the
20
+ * `T` type parameter on the metadata hooks for typed field access; it defaults to
21
+ * an open record.
22
+ */
14
23
  type Metadata = Record<string, any>;
15
- type FilesMetadata = Record<string, Metadata>;
24
+ /** The whole metadata store: a map from repo-relative file path to its frontmatter. */
25
+ type FilesMetadata<T = Metadata> = Record<string, T>;
26
+ /** The paths a {@link MetadataQueryFunction} selected. */
16
27
  type FileQueryResult = string[];
17
- type MetadataQueryFunction = (filesMetadata: FilesMetadata) => FileQueryResult;
18
- type MetadataQueryResult = {
19
- result: FileQueryResult;
20
- } | {
21
- error: any;
28
+ /**
29
+ * A query over the metadata store: receive every file's frontmatter keyed by path
30
+ * and return the paths that match. Plain JS — `Object.entries(...).filter(...)` —
31
+ * no query language to learn.
32
+ */
33
+ type MetadataQueryFunction<T = Metadata> = (filesMetadata: FilesMetadata<T>) => FileQueryResult;
34
+ /** One match from {@link MetadataQueryFunction}: the file path paired with its frontmatter. */
35
+ type MetadataQueryEntry<T = Metadata> = {
36
+ path: string;
37
+ meta: T;
38
+ };
39
+ /**
40
+ * The result of running a metadata query: the matched entries (path + frontmatter),
41
+ * or the error a throwing query produced.
42
+ */
43
+ type MetadataQueryResult<T = Metadata> = MetadataQueryEntry<T>[] | {
44
+ error: unknown;
22
45
  };
23
46
 
24
- export type { EvaluationContext, FileQueryResult, FilesMetadata, Metadata, MetadataQueryFunction, MetadataQueryResult, ModuleExports };
47
+ export type { EvaluationContext, FileQueryResult, FilesMetadata, Metadata, MetadataQueryEntry, MetadataQueryFunction, MetadataQueryResult, ModuleExports };
@@ -1,4 +1,8 @@
1
+ /** The exports object of an evaluated sandbox module (untyped — shape depends on the module). */
1
2
  type ModuleExports = any;
3
+ /** The sandbox runtime's per-module evaluation context: a module's exports plus the
4
+ * helpers to dynamically import, resolve, and re-evaluate other modules.
5
+ * (The real type is `EvaluationContext` from `src/bundler/module/Evaluation.ts`.) */
2
6
  type EvaluationContext = {
3
7
  exports: ModuleExports;
4
8
  dynamicImport: (moduleToImport: string, symbolToImport: string) => Promise<ModuleExports>;
@@ -11,14 +15,33 @@ type EvaluationContext = {
11
15
  };
12
16
  };
13
17
  };
18
+ /**
19
+ * The parsed frontmatter of a single file. Apps can supply their own shape as the
20
+ * `T` type parameter on the metadata hooks for typed field access; it defaults to
21
+ * an open record.
22
+ */
14
23
  type Metadata = Record<string, any>;
15
- type FilesMetadata = Record<string, Metadata>;
24
+ /** The whole metadata store: a map from repo-relative file path to its frontmatter. */
25
+ type FilesMetadata<T = Metadata> = Record<string, T>;
26
+ /** The paths a {@link MetadataQueryFunction} selected. */
16
27
  type FileQueryResult = string[];
17
- type MetadataQueryFunction = (filesMetadata: FilesMetadata) => FileQueryResult;
18
- type MetadataQueryResult = {
19
- result: FileQueryResult;
20
- } | {
21
- error: any;
28
+ /**
29
+ * A query over the metadata store: receive every file's frontmatter keyed by path
30
+ * and return the paths that match. Plain JS — `Object.entries(...).filter(...)` —
31
+ * no query language to learn.
32
+ */
33
+ type MetadataQueryFunction<T = Metadata> = (filesMetadata: FilesMetadata<T>) => FileQueryResult;
34
+ /** One match from {@link MetadataQueryFunction}: the file path paired with its frontmatter. */
35
+ type MetadataQueryEntry<T = Metadata> = {
36
+ path: string;
37
+ meta: T;
38
+ };
39
+ /**
40
+ * The result of running a metadata query: the matched entries (path + frontmatter),
41
+ * or the error a throwing query produced.
42
+ */
43
+ type MetadataQueryResult<T = Metadata> = MetadataQueryEntry<T>[] | {
44
+ error: unknown;
22
45
  };
23
46
 
24
- export type { EvaluationContext, FileQueryResult, FilesMetadata, Metadata, MetadataQueryFunction, MetadataQueryResult, ModuleExports };
47
+ export type { EvaluationContext, FileQueryResult, FilesMetadata, Metadata, MetadataQueryEntry, MetadataQueryFunction, MetadataQueryResult, ModuleExports };
package/dist/version.cjs CHANGED
@@ -21,7 +21,7 @@ __export(version_exports, {
21
21
  SDK_VERSION: () => SDK_VERSION
22
22
  });
23
23
  module.exports = __toCommonJS(version_exports);
24
- const SDK_VERSION = "0.15.0";
24
+ const SDK_VERSION = "0.17.0";
25
25
  // Annotate the CommonJS export names for ESM import in node:
26
26
  0 && (module.exports = {
27
27
  SDK_VERSION
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/version.ts"],"sourcesContent":["// GENERATED by scripts/gen-version.mjs from package.json — do not edit by hand.\n// Regenerated on every build (prebuild); kept honest by version.test.ts.\n\n/** This SDK's package version, baked from package.json at build (SP2-6). */\nexport const SDK_VERSION = '0.15.0';\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAIO,MAAM,cAAc;","names":[]}
1
+ {"version":3,"sources":["../src/version.ts"],"sourcesContent":["// GENERATED by scripts/gen-version.mjs from package.json — do not edit by hand.\n// Regenerated on every build (prebuild); kept honest by version.test.ts.\n\n/** This SDK's package version, baked from package.json at build (SP2-6). */\nexport const SDK_VERSION = '0.17.0';\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAIO,MAAM,cAAc;","names":[]}
@@ -1,4 +1,4 @@
1
1
  /** This SDK's package version, baked from package.json at build (SP2-6). */
2
- declare const SDK_VERSION = "0.15.0";
2
+ declare const SDK_VERSION = "0.17.0";
3
3
 
4
4
  export { SDK_VERSION };
package/dist/version.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  /** This SDK's package version, baked from package.json at build (SP2-6). */
2
- declare const SDK_VERSION = "0.15.0";
2
+ declare const SDK_VERSION = "0.17.0";
3
3
 
4
4
  export { SDK_VERSION };
package/dist/version.js CHANGED
@@ -1,4 +1,4 @@
1
- const SDK_VERSION = "0.15.0";
1
+ const SDK_VERSION = "0.17.0";
2
2
  export {
3
3
  SDK_VERSION
4
4
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/version.ts"],"sourcesContent":["// GENERATED by scripts/gen-version.mjs from package.json — do not edit by hand.\n// Regenerated on every build (prebuild); kept honest by version.test.ts.\n\n/** This SDK's package version, baked from package.json at build (SP2-6). */\nexport const SDK_VERSION = '0.15.0';\n"],"mappings":"AAIO,MAAM,cAAc;","names":[]}
1
+ {"version":3,"sources":["../src/version.ts"],"sourcesContent":["// GENERATED by scripts/gen-version.mjs from package.json — do not edit by hand.\n// Regenerated on every build (prebuild); kept honest by version.test.ts.\n\n/** This SDK's package version, baked from package.json at build (SP2-6). */\nexport const SDK_VERSION = '0.17.0';\n"],"mappings":"AAIO,MAAM,cAAc;","names":[]}