@immediately-run/sdk 0.45.3 → 0.47.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 (219) hide show
  1. package/dist/MDXProvider.cjs +1 -5
  2. package/dist/MDXProvider.cjs.map +1 -1
  3. package/dist/MDXProvider.js +1 -5
  4. package/dist/MDXProvider.js.map +1 -1
  5. package/dist/RoutingSpec.cjs.map +1 -1
  6. package/dist/TinkerableContext.cjs.map +1 -1
  7. package/dist/TinkerableContext.js.map +1 -1
  8. package/dist/auth.cjs.map +1 -1
  9. package/dist/auth.js.map +1 -1
  10. package/dist/boot.cjs +2 -9
  11. package/dist/boot.cjs.map +1 -1
  12. package/dist/boot.d.cts +2 -2
  13. package/dist/boot.d.ts +2 -2
  14. package/dist/boot.js +2 -9
  15. package/dist/boot.js.map +1 -1
  16. package/dist/catalog.cjs.map +1 -1
  17. package/dist/catalog.js.map +1 -1
  18. package/dist/components/Admonition.cjs +4 -13
  19. package/dist/components/Admonition.cjs.map +1 -1
  20. package/dist/components/Admonition.js +4 -13
  21. package/dist/components/Admonition.js.map +1 -1
  22. package/dist/components/FileRouter.cjs +11 -3
  23. package/dist/components/FileRouter.cjs.map +1 -1
  24. package/dist/components/FileRouter.js +11 -3
  25. package/dist/components/FileRouter.js.map +1 -1
  26. package/dist/components/HeadingAnchor.cjs.map +1 -1
  27. package/dist/components/HeadingAnchor.js.map +1 -1
  28. package/dist/components/Link.cjs.map +1 -1
  29. package/dist/components/Link.js.map +1 -1
  30. package/dist/components/MainContent.cjs +11 -1
  31. package/dist/components/MainContent.cjs.map +1 -1
  32. package/dist/components/MainContent.js +11 -1
  33. package/dist/components/MainContent.js.map +1 -1
  34. package/dist/components/MountImage.cjs +1 -9
  35. package/dist/components/MountImage.cjs.map +1 -1
  36. package/dist/components/MountImage.js +1 -9
  37. package/dist/components/MountImage.js.map +1 -1
  38. package/dist/components/Routes.cjs +1 -4
  39. package/dist/components/Routes.cjs.map +1 -1
  40. package/dist/components/Routes.d.cts +1 -1
  41. package/dist/components/Routes.d.ts +1 -1
  42. package/dist/components/Routes.js +1 -4
  43. package/dist/components/Routes.js.map +1 -1
  44. package/dist/components/SafeInclude.cjs +1 -4
  45. package/dist/components/SafeInclude.cjs.map +1 -1
  46. package/dist/components/SafeInclude.js +1 -4
  47. package/dist/components/SafeInclude.js.map +1 -1
  48. package/dist/components/WikiLink.cjs +1 -10
  49. package/dist/components/WikiLink.cjs.map +1 -1
  50. package/dist/components/WikiLink.js +1 -10
  51. package/dist/components/WikiLink.js.map +1 -1
  52. package/dist/components/defaults.cjs.map +1 -1
  53. package/dist/components/defaults.d.cts +1 -1
  54. package/dist/components/defaults.d.ts +1 -1
  55. package/dist/components/defaults.js.map +1 -1
  56. package/dist/components/errors.cjs +3 -1
  57. package/dist/components/errors.cjs.map +1 -1
  58. package/dist/components/errors.js +3 -1
  59. package/dist/components/errors.js.map +1 -1
  60. package/dist/contextUtils.cjs.map +1 -1
  61. package/dist/contextUtils.js.map +1 -1
  62. package/dist/contribute.cjs.map +1 -1
  63. package/dist/contribute.js.map +1 -1
  64. package/dist/debug.cjs +2 -1
  65. package/dist/debug.cjs.map +1 -1
  66. package/dist/debug.js +3 -8
  67. package/dist/debug.js.map +1 -1
  68. package/dist/diagnostics.cjs.map +1 -1
  69. package/dist/diagnostics.js.map +1 -1
  70. package/dist/editor.cjs.map +1 -1
  71. package/dist/editor.js.map +1 -1
  72. package/dist/editorContext.cjs.map +1 -1
  73. package/dist/editorContext.js.map +1 -1
  74. package/dist/fs.cjs.map +1 -1
  75. package/dist/fs.js.map +1 -1
  76. package/dist/hostAttention.cjs +57 -0
  77. package/dist/hostAttention.cjs.map +1 -0
  78. package/dist/hostAttention.d.cts +39 -0
  79. package/dist/hostAttention.d.ts +39 -0
  80. package/dist/hostAttention.js +31 -0
  81. package/dist/hostAttention.js.map +1 -0
  82. package/dist/hostTransport.cjs +55 -0
  83. package/dist/hostTransport.cjs.map +1 -0
  84. package/dist/hostTransport.d.cts +12 -0
  85. package/dist/hostTransport.d.ts +12 -0
  86. package/dist/hostTransport.js +30 -0
  87. package/dist/hostTransport.js.map +1 -0
  88. package/dist/index.cjs +4 -0
  89. package/dist/index.cjs.map +1 -1
  90. package/dist/index.d.cts +3 -1
  91. package/dist/index.d.ts +3 -1
  92. package/dist/index.js +2 -0
  93. package/dist/index.js.map +1 -1
  94. package/dist/injectedBundler.cjs.map +1 -1
  95. package/dist/injectedBundler.js.map +1 -1
  96. package/dist/ipc.cjs +1 -4
  97. package/dist/ipc.cjs.map +1 -1
  98. package/dist/ipc.js +1 -4
  99. package/dist/ipc.js.map +1 -1
  100. package/dist/irMarkers.cjs.map +1 -1
  101. package/dist/irMarkers.d.cts +11 -11
  102. package/dist/irMarkers.d.ts +11 -11
  103. package/dist/irMarkers.js.map +1 -1
  104. package/dist/launch.cjs.map +1 -1
  105. package/dist/launch.js.map +1 -1
  106. package/dist/linkSpace.cjs +11 -2
  107. package/dist/linkSpace.cjs.map +1 -1
  108. package/dist/linkSpace.d.cts +23 -0
  109. package/dist/linkSpace.d.ts +23 -0
  110. package/dist/linkSpace.js +11 -2
  111. package/dist/linkSpace.js.map +1 -1
  112. package/dist/llm.cjs +26 -8
  113. package/dist/llm.cjs.map +1 -1
  114. package/dist/llm.d.cts +75 -3
  115. package/dist/llm.d.ts +75 -3
  116. package/dist/llm.js +21 -7
  117. package/dist/llm.js.map +1 -1
  118. package/dist/loading.cjs +18 -14
  119. package/dist/loading.cjs.map +1 -1
  120. package/dist/loading.d.cts +2 -2
  121. package/dist/loading.d.ts +2 -2
  122. package/dist/loading.js +19 -19
  123. package/dist/loading.js.map +1 -1
  124. package/dist/markers.cjs.map +1 -1
  125. package/dist/markers.js.map +1 -1
  126. package/dist/metadataSource.cjs +1 -5
  127. package/dist/metadataSource.cjs.map +1 -1
  128. package/dist/metadataSource.d.cts +1 -1
  129. package/dist/metadataSource.d.ts +1 -1
  130. package/dist/metadataSource.js +1 -5
  131. package/dist/metadataSource.js.map +1 -1
  132. package/dist/moduleCache.cjs +4 -1
  133. package/dist/moduleCache.cjs.map +1 -1
  134. package/dist/moduleCache.d.cts +1 -1
  135. package/dist/moduleCache.d.ts +1 -1
  136. package/dist/moduleCache.js +4 -1
  137. package/dist/moduleCache.js.map +1 -1
  138. package/dist/mountMatch.cjs.map +1 -1
  139. package/dist/mountMatch.js.map +1 -1
  140. package/dist/mounts.cjs +6 -1
  141. package/dist/mounts.cjs.map +1 -1
  142. package/dist/mounts.d.cts +2 -2
  143. package/dist/mounts.d.ts +2 -2
  144. package/dist/mounts.js +6 -1
  145. package/dist/mounts.js.map +1 -1
  146. package/dist/netFetch.cjs +3 -5
  147. package/dist/netFetch.cjs.map +1 -1
  148. package/dist/netFetch.js +3 -5
  149. package/dist/netFetch.js.map +1 -1
  150. package/dist/onFsChange.cjs.map +1 -1
  151. package/dist/onFsChange.js.map +1 -1
  152. package/dist/pathUtils.cjs +9 -12
  153. package/dist/pathUtils.cjs.map +1 -1
  154. package/dist/pathUtils.js +9 -12
  155. package/dist/pathUtils.js.map +1 -1
  156. package/dist/protocolDeadline.cjs +205 -0
  157. package/dist/protocolDeadline.cjs.map +1 -0
  158. package/dist/protocolDeadline.d.cts +146 -0
  159. package/dist/protocolDeadline.d.ts +146 -0
  160. package/dist/protocolDeadline.js +168 -0
  161. package/dist/protocolDeadline.js.map +1 -0
  162. package/dist/protocolStream.cjs +49 -6
  163. package/dist/protocolStream.cjs.map +1 -1
  164. package/dist/protocolStream.d.cts +9 -2
  165. package/dist/protocolStream.d.ts +9 -2
  166. package/dist/protocolStream.js +56 -6
  167. package/dist/protocolStream.js.map +1 -1
  168. package/dist/pushChannel.cjs +13 -9
  169. package/dist/pushChannel.cjs.map +1 -1
  170. package/dist/pushChannel.js +12 -8
  171. package/dist/pushChannel.js.map +1 -1
  172. package/dist/ready.cjs.map +1 -1
  173. package/dist/ready.js.map +1 -1
  174. package/dist/routing.cjs +3 -1
  175. package/dist/routing.cjs.map +1 -1
  176. package/dist/routing.js +3 -1
  177. package/dist/routing.js.map +1 -1
  178. package/dist/safeContent/index.cjs.map +1 -1
  179. package/dist/safeContent/index.js.map +1 -1
  180. package/dist/safeContent/parseSafeMdast.cjs.map +1 -1
  181. package/dist/safeContent/parseSafeMdast.js.map +1 -1
  182. package/dist/safeContent/renderMdast.cjs.map +1 -1
  183. package/dist/safeContent/renderMdast.js.map +1 -1
  184. package/dist/sandboxTypes.cjs.map +1 -1
  185. package/dist/sandboxUtils.cjs +69 -24
  186. package/dist/sandboxUtils.cjs.map +1 -1
  187. package/dist/sandboxUtils.d.cts +37 -4
  188. package/dist/sandboxUtils.d.ts +37 -4
  189. package/dist/sandboxUtils.js +74 -22
  190. package/dist/sandboxUtils.js.map +1 -1
  191. package/dist/scrollToId.cjs.map +1 -1
  192. package/dist/scrollToId.js.map +1 -1
  193. package/dist/secrets.cjs.map +1 -1
  194. package/dist/secrets.js.map +1 -1
  195. package/dist/tasks.cjs +12 -2
  196. package/dist/tasks.cjs.map +1 -1
  197. package/dist/tasks.js +12 -2
  198. package/dist/tasks.js.map +1 -1
  199. package/dist/testing.cjs +1 -3
  200. package/dist/testing.cjs.map +1 -1
  201. package/dist/testing.js +1 -3
  202. package/dist/testing.js.map +1 -1
  203. package/dist/theme.cjs.map +1 -1
  204. package/dist/theme.js.map +1 -1
  205. package/dist/urlUtils.cjs +7 -18
  206. package/dist/urlUtils.cjs.map +1 -1
  207. package/dist/urlUtils.js +7 -18
  208. package/dist/urlUtils.js.map +1 -1
  209. package/dist/vcs.cjs +1 -3
  210. package/dist/vcs.cjs.map +1 -1
  211. package/dist/vcs.js +1 -3
  212. package/dist/vcs.js.map +1 -1
  213. package/dist/version.cjs +1 -1
  214. package/dist/version.cjs.map +1 -1
  215. package/dist/version.d.cts +1 -1
  216. package/dist/version.d.ts +1 -1
  217. package/dist/version.js +1 -1
  218. package/dist/version.js.map +1 -1
  219. package/package.json +11 -5
@@ -44,11 +44,7 @@ function MDXProvider(properties) {
44
44
  } else {
45
45
  allComponents = useMDXComponents(properties.components);
46
46
  }
47
- return (0, import_react.createElement)(
48
- MDXContext.Provider,
49
- { value: allComponents },
50
- properties.children
51
- );
47
+ return (0, import_react.createElement)(MDXContext.Provider, { value: allComponents }, properties.children);
52
48
  }
53
49
  // Annotate the CommonJS export names for ESM import in node:
54
50
  0 && (module.exports = {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/MDXProvider.ts"],"sourcesContent":["// Based on https://github.com/mdx-js/mdx/blob/main/packages/react/lib/index.js\n// since sandpack-bundler cannot import @mdx-js/react as it chokes on the\n// transitive dependency on VFile.\nimport {createContext, useContext, useMemo, createElement} from 'react'\nconst emptyComponents = {}\n\nconst MDXContext = createContext(emptyComponents);\n\n/** Merge the caller's MDX component overrides with those from the surrounding\n * {@link MDXProvider} context (a function arg receives the parent set to merge). */\nexport function useMDXComponents(components:any) {\n const contextComponents = useContext(MDXContext)\n\n // Memoize to avoid unnecessary top-level context changes\n return useMemo(\n function () {\n // Custom merge via a function prop\n if (typeof components === 'function') {\n return components(contextComponents)\n }\n\n return {...contextComponents, ...components}\n },\n [contextComponents, components]\n )\n}\n\n/** Provide MDX component overrides (e.g. a custom `a`/`h1`) to the rendered\n * subtree; transformed `.mdx` modules pick them up. */\nexport function MDXProvider(properties:any) {\n\n let allComponents: any\n\n if (properties.disableParentContext) {\n allComponents =\n typeof properties.components === 'function'\n ? properties.components(emptyComponents)\n : properties.components || emptyComponents\n } else {\n allComponents = useMDXComponents(properties.components)\n }\n\n return createElement(\n MDXContext.Provider,\n {value: allComponents},\n properties.children\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,mBAAgE;AAChE,MAAM,kBAAkB,CAAC;AAEzB,MAAM,iBAAa,4BAAc,eAAe;AAIzC,SAAS,iBAAiB,YAAgB;AAC/C,QAAM,wBAAoB,yBAAW,UAAU;AAG/C,aAAO;AAAA,IACL,WAAY;AAEV,UAAI,OAAO,eAAe,YAAY;AACpC,eAAO,WAAW,iBAAiB;AAAA,MACrC;AAEA,aAAO,EAAC,GAAG,mBAAmB,GAAG,WAAU;AAAA,IAC7C;AAAA,IACA,CAAC,mBAAmB,UAAU;AAAA,EAChC;AACF;AAIO,SAAS,YAAY,YAAgB;AAE1C,MAAI;AAEJ,MAAI,WAAW,sBAAsB;AACnC,oBACE,OAAO,WAAW,eAAe,aAC7B,WAAW,WAAW,eAAe,IACrC,WAAW,cAAc;AAAA,EACjC,OAAO;AACL,oBAAgB,iBAAiB,WAAW,UAAU;AAAA,EACxD;AAEA,aAAO;AAAA,IACL,WAAW;AAAA,IACX,EAAC,OAAO,cAAa;AAAA,IACrB,WAAW;AAAA,EACb;AACF;","names":[]}
1
+ {"version":3,"sources":["../src/MDXProvider.ts"],"sourcesContent":["// Based on https://github.com/mdx-js/mdx/blob/main/packages/react/lib/index.js\n// since sandpack-bundler cannot import @mdx-js/react as it chokes on the\n// transitive dependency on VFile.\nimport { createContext, useContext, useMemo, createElement } from 'react';\nconst emptyComponents = {};\n\nconst MDXContext = createContext(emptyComponents);\n\n/** Merge the caller's MDX component overrides with those from the surrounding\n * {@link MDXProvider} context (a function arg receives the parent set to merge). */\nexport function useMDXComponents(components: any) {\n const contextComponents = useContext(MDXContext);\n\n // Memoize to avoid unnecessary top-level context changes\n return useMemo(\n function () {\n // Custom merge via a function prop\n if (typeof components === 'function') {\n return components(contextComponents);\n }\n\n return { ...contextComponents, ...components };\n },\n [contextComponents, components],\n );\n}\n\n/** Provide MDX component overrides (e.g. a custom `a`/`h1`) to the rendered\n * subtree; transformed `.mdx` modules pick them up. */\nexport function MDXProvider(properties: any) {\n let allComponents: any;\n\n if (properties.disableParentContext) {\n allComponents =\n typeof properties.components === 'function'\n ? properties.components(emptyComponents)\n : properties.components || emptyComponents;\n } else {\n allComponents = useMDXComponents(properties.components);\n }\n\n return createElement(MDXContext.Provider, { value: allComponents }, properties.children);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,mBAAkE;AAClE,MAAM,kBAAkB,CAAC;AAEzB,MAAM,iBAAa,4BAAc,eAAe;AAIzC,SAAS,iBAAiB,YAAiB;AAChD,QAAM,wBAAoB,yBAAW,UAAU;AAG/C,aAAO;AAAA,IACL,WAAY;AAEV,UAAI,OAAO,eAAe,YAAY;AACpC,eAAO,WAAW,iBAAiB;AAAA,MACrC;AAEA,aAAO,EAAE,GAAG,mBAAmB,GAAG,WAAW;AAAA,IAC/C;AAAA,IACA,CAAC,mBAAmB,UAAU;AAAA,EAChC;AACF;AAIO,SAAS,YAAY,YAAiB;AAC3C,MAAI;AAEJ,MAAI,WAAW,sBAAsB;AACnC,oBACE,OAAO,WAAW,eAAe,aAC7B,WAAW,WAAW,eAAe,IACrC,WAAW,cAAc;AAAA,EACjC,OAAO;AACL,oBAAgB,iBAAiB,WAAW,UAAU;AAAA,EACxD;AAEA,aAAO,4BAAc,WAAW,UAAU,EAAE,OAAO,cAAc,GAAG,WAAW,QAAQ;AACzF;","names":[]}
@@ -21,11 +21,7 @@ function MDXProvider(properties) {
21
21
  } else {
22
22
  allComponents = useMDXComponents(properties.components);
23
23
  }
24
- return createElement(
25
- MDXContext.Provider,
26
- { value: allComponents },
27
- properties.children
28
- );
24
+ return createElement(MDXContext.Provider, { value: allComponents }, properties.children);
29
25
  }
30
26
  export {
31
27
  MDXProvider,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/MDXProvider.ts"],"sourcesContent":["// Based on https://github.com/mdx-js/mdx/blob/main/packages/react/lib/index.js\n// since sandpack-bundler cannot import @mdx-js/react as it chokes on the\n// transitive dependency on VFile.\nimport {createContext, useContext, useMemo, createElement} from 'react'\nconst emptyComponents = {}\n\nconst MDXContext = createContext(emptyComponents);\n\n/** Merge the caller's MDX component overrides with those from the surrounding\n * {@link MDXProvider} context (a function arg receives the parent set to merge). */\nexport function useMDXComponents(components:any) {\n const contextComponents = useContext(MDXContext)\n\n // Memoize to avoid unnecessary top-level context changes\n return useMemo(\n function () {\n // Custom merge via a function prop\n if (typeof components === 'function') {\n return components(contextComponents)\n }\n\n return {...contextComponents, ...components}\n },\n [contextComponents, components]\n )\n}\n\n/** Provide MDX component overrides (e.g. a custom `a`/`h1`) to the rendered\n * subtree; transformed `.mdx` modules pick them up. */\nexport function MDXProvider(properties:any) {\n\n let allComponents: any\n\n if (properties.disableParentContext) {\n allComponents =\n typeof properties.components === 'function'\n ? properties.components(emptyComponents)\n : properties.components || emptyComponents\n } else {\n allComponents = useMDXComponents(properties.components)\n }\n\n return createElement(\n MDXContext.Provider,\n {value: allComponents},\n properties.children\n )\n}\n"],"mappings":";AAGA,SAAQ,eAAe,YAAY,SAAS,qBAAoB;AAChE,MAAM,kBAAkB,CAAC;AAEzB,MAAM,aAAa,cAAc,eAAe;AAIzC,SAAS,iBAAiB,YAAgB;AAC/C,QAAM,oBAAoB,WAAW,UAAU;AAG/C,SAAO;AAAA,IACL,WAAY;AAEV,UAAI,OAAO,eAAe,YAAY;AACpC,eAAO,WAAW,iBAAiB;AAAA,MACrC;AAEA,aAAO,EAAC,GAAG,mBAAmB,GAAG,WAAU;AAAA,IAC7C;AAAA,IACA,CAAC,mBAAmB,UAAU;AAAA,EAChC;AACF;AAIO,SAAS,YAAY,YAAgB;AAE1C,MAAI;AAEJ,MAAI,WAAW,sBAAsB;AACnC,oBACE,OAAO,WAAW,eAAe,aAC7B,WAAW,WAAW,eAAe,IACrC,WAAW,cAAc;AAAA,EACjC,OAAO;AACL,oBAAgB,iBAAiB,WAAW,UAAU;AAAA,EACxD;AAEA,SAAO;AAAA,IACL,WAAW;AAAA,IACX,EAAC,OAAO,cAAa;AAAA,IACrB,WAAW;AAAA,EACb;AACF;","names":[]}
1
+ {"version":3,"sources":["../src/MDXProvider.ts"],"sourcesContent":["// Based on https://github.com/mdx-js/mdx/blob/main/packages/react/lib/index.js\n// since sandpack-bundler cannot import @mdx-js/react as it chokes on the\n// transitive dependency on VFile.\nimport { createContext, useContext, useMemo, createElement } from 'react';\nconst emptyComponents = {};\n\nconst MDXContext = createContext(emptyComponents);\n\n/** Merge the caller's MDX component overrides with those from the surrounding\n * {@link MDXProvider} context (a function arg receives the parent set to merge). */\nexport function useMDXComponents(components: any) {\n const contextComponents = useContext(MDXContext);\n\n // Memoize to avoid unnecessary top-level context changes\n return useMemo(\n function () {\n // Custom merge via a function prop\n if (typeof components === 'function') {\n return components(contextComponents);\n }\n\n return { ...contextComponents, ...components };\n },\n [contextComponents, components],\n );\n}\n\n/** Provide MDX component overrides (e.g. a custom `a`/`h1`) to the rendered\n * subtree; transformed `.mdx` modules pick them up. */\nexport function MDXProvider(properties: any) {\n let allComponents: any;\n\n if (properties.disableParentContext) {\n allComponents =\n typeof properties.components === 'function'\n ? properties.components(emptyComponents)\n : properties.components || emptyComponents;\n } else {\n allComponents = useMDXComponents(properties.components);\n }\n\n return createElement(MDXContext.Provider, { value: allComponents }, properties.children);\n}\n"],"mappings":";AAGA,SAAS,eAAe,YAAY,SAAS,qBAAqB;AAClE,MAAM,kBAAkB,CAAC;AAEzB,MAAM,aAAa,cAAc,eAAe;AAIzC,SAAS,iBAAiB,YAAiB;AAChD,QAAM,oBAAoB,WAAW,UAAU;AAG/C,SAAO;AAAA,IACL,WAAY;AAEV,UAAI,OAAO,eAAe,YAAY;AACpC,eAAO,WAAW,iBAAiB;AAAA,MACrC;AAEA,aAAO,EAAE,GAAG,mBAAmB,GAAG,WAAW;AAAA,IAC/C;AAAA,IACA,CAAC,mBAAmB,UAAU;AAAA,EAChC;AACF;AAIO,SAAS,YAAY,YAAiB;AAC3C,MAAI;AAEJ,MAAI,WAAW,sBAAsB;AACnC,oBACE,OAAO,WAAW,eAAe,aAC7B,WAAW,WAAW,eAAe,IACrC,WAAW,cAAc;AAAA,EACjC,OAAO;AACL,oBAAgB,iBAAiB,WAAW,UAAU;AAAA,EACxD;AAEA,SAAO,cAAc,WAAW,UAAU,EAAE,OAAO,cAAc,GAAG,WAAW,QAAQ;AACzF;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/RoutingSpec.ts"],"sourcesContent":["import type { FC, ReactNode } from 'react';\n\n/** Named parameters extracted from a route match (`:name` segments, `*` rest). */\nexport type RouteParams = Record<string, string>;\n\n/** A route target that receives the matched params as a prop. */\nexport type RouteComponent = FC<{ params: RouteParams }>;\n\nexport type RoutingRule = {\n name?: string;\n /**\n * What to match against the app-owned `sandboxPath`. A string is a path\n * template (`/posts/:slug`, `/files/*`, or a literal like `/`) compiled to an\n * anchored regex; a `RegExp` is used as authored (the escape hatch — you own\n * anchoring).\n */\n pattern: string | RegExp;\n /** Element to render for this route. Reads params via `useRouteParams()`. */\n element?: ReactNode;\n /** Component to render for this route; receives the matched params as a prop. */\n component?: RouteComponent;\n /** @deprecated Use `element`. Accepted for backward compatibility. */\n reactNode?: ReactNode;\n};\n\nexport type RoutingSpec = {\n routes: RoutingRule[];\n}\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
1
+ {"version":3,"sources":["../src/RoutingSpec.ts"],"sourcesContent":["import type { FC, ReactNode } from 'react';\n\n/** Named parameters extracted from a route match (`:name` segments, `*` rest). */\nexport type RouteParams = Record<string, string>;\n\n/** A route target that receives the matched params as a prop. */\nexport type RouteComponent = FC<{ params: RouteParams }>;\n\nexport type RoutingRule = {\n name?: string;\n /**\n * What to match against the app-owned `sandboxPath`. A string is a path\n * template (`/posts/:slug`, `/files/*`, or a literal like `/`) compiled to an\n * anchored regex; a `RegExp` is used as authored (the escape hatch — you own\n * anchoring).\n */\n pattern: string | RegExp;\n /** Element to render for this route. Reads params via `useRouteParams()`. */\n element?: ReactNode;\n /** Component to render for this route; receives the matched params as a prop. */\n component?: RouteComponent;\n /** @deprecated Use `element`. Accepted for backward compatibility. */\n reactNode?: ReactNode;\n};\n\nexport type RoutingSpec = {\n routes: RoutingRule[];\n};\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/TinkerableContext.ts"],"sourcesContent":["import {createContext} from 'react';\nimport { RoutingRule, RoutingSpec } from './RoutingSpec';\nimport { FilesMetadata } from './sandboxTypes';\n\n\nexport type PathState = {\n mode:string,\n namespace:string,\n provider:string,\n repository:string,\n ref:string,\n sandboxPath:string,\n pathParameters?: Record<string, string>\n routingRule?: RoutingRule\n}\n\nexport type NavigationState = PathState & {\n hash:string,\n search:string,\n}\n\nexport type TinkerableState = {\n outerHref: string,\n navigationState: NavigationState,\n routingSpec: RoutingSpec,\n filesMetadata: FilesMetadata;\n}\n\nexport const TinkerableContext = createContext<TinkerableState>({} as TinkerableState);\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA4B;AA4BrB,MAAM,wBAAoB,4BAA+B,CAAC,CAAoB;","names":[]}
1
+ {"version":3,"sources":["../src/TinkerableContext.ts"],"sourcesContent":["import { createContext } from 'react';\nimport { RoutingRule, RoutingSpec } from './RoutingSpec';\nimport { FilesMetadata } from './sandboxTypes';\n\nexport type PathState = {\n mode: string;\n namespace: string;\n provider: string;\n repository: string;\n ref: string;\n sandboxPath: string;\n pathParameters?: Record<string, string>;\n routingRule?: RoutingRule;\n};\n\nexport type NavigationState = PathState & {\n hash: string;\n search: string;\n};\n\nexport type TinkerableState = {\n outerHref: string;\n navigationState: NavigationState;\n routingSpec: RoutingSpec;\n filesMetadata: FilesMetadata;\n};\n\nexport const TinkerableContext = createContext<TinkerableState>({} as TinkerableState);\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA8B;AA2BvB,MAAM,wBAAoB,4BAA+B,CAAC,CAAoB;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/TinkerableContext.ts"],"sourcesContent":["import {createContext} from 'react';\nimport { RoutingRule, RoutingSpec } from './RoutingSpec';\nimport { FilesMetadata } from './sandboxTypes';\n\n\nexport type PathState = {\n mode:string,\n namespace:string,\n provider:string,\n repository:string,\n ref:string,\n sandboxPath:string,\n pathParameters?: Record<string, string>\n routingRule?: RoutingRule\n}\n\nexport type NavigationState = PathState & {\n hash:string,\n search:string,\n}\n\nexport type TinkerableState = {\n outerHref: string,\n navigationState: NavigationState,\n routingSpec: RoutingSpec,\n filesMetadata: FilesMetadata;\n}\n\nexport const TinkerableContext = createContext<TinkerableState>({} as TinkerableState);\n"],"mappings":";AAAA,SAAQ,qBAAoB;AA4BrB,MAAM,oBAAoB,cAA+B,CAAC,CAAoB;","names":[]}
1
+ {"version":3,"sources":["../src/TinkerableContext.ts"],"sourcesContent":["import { createContext } from 'react';\nimport { RoutingRule, RoutingSpec } from './RoutingSpec';\nimport { FilesMetadata } from './sandboxTypes';\n\nexport type PathState = {\n mode: string;\n namespace: string;\n provider: string;\n repository: string;\n ref: string;\n sandboxPath: string;\n pathParameters?: Record<string, string>;\n routingRule?: RoutingRule;\n};\n\nexport type NavigationState = PathState & {\n hash: string;\n search: string;\n};\n\nexport type TinkerableState = {\n outerHref: string;\n navigationState: NavigationState;\n routingSpec: RoutingSpec;\n filesMetadata: FilesMetadata;\n};\n\nexport const TinkerableContext = createContext<TinkerableState>({} as TinkerableState);\n"],"mappings":";AAAA,SAAS,qBAAqB;AA2BvB,MAAM,oBAAoB,cAA+B,CAAC,CAAoB;","names":[]}
package/dist/auth.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/auth.ts"],"sourcesContent":["import { createPushChannel } from './pushChannel';\nimport { AUTH_STATE, REQUEST_AUTH_STATE } from './generated/protocol';\n\n/**\n * Login / account state of the immediately.run user, mirrored from the host\n * window into the sandbox.\n *\n * `status` is `'unknown'` until the host has reported a value (use it to\n * distinguish \"still loading\" from a confirmed signed-out session).\n */\nexport type AuthStatus = 'unknown' | 'signed-in' | 'signed-out';\n\n/** The signed-in immediately.run user, as seen by the sandbox (no token, ever). */\nexport interface SandboxUser {\n /** GitHub login (handle) of the signed-in user. */\n login: string;\n}\n\n/** The user's login / account state: a `status` plus the `user` when signed in. */\nexport interface AuthState {\n status: AuthStatus;\n user: SandboxUser | null;\n}\n\nconst isAuthState = (v: unknown): v is AuthState => {\n const s = v as Partial<AuthState> | null;\n return (\n !!s &&\n (s.status === 'unknown' || s.status === 'signed-in' || s.status === 'signed-out') &&\n (s.user === null || (typeof s.user === 'object' && typeof (s.user as SandboxUser).login === 'string'))\n );\n};\n\n// Read over the transport (SDK_PACKAGING_SPEC §4): the host pushes `auth-state`\n// and answers `request-auth-state` (wire format: site-main channelBridge.ts).\nconst channel = createPushChannel<AuthState>({\n pushType: AUTH_STATE,\n requestType: REQUEST_AUTH_STATE,\n initial: { status: 'unknown', user: null },\n parse: (msg) => (isAuthState(msg.state) ? (msg.state as AuthState) : undefined),\n});\n\n/**\n * Returns the current login / account state. Poll this whenever you need a\n * one-off read; use {@link onAuthChange} or {@link useAuth} to react to changes.\n */\nexport const getAuthState = (): AuthState => channel.get();\n\n/**\n * Subscribe to login / logout changes. The listener is invoked immediately with\n * the current state, then again on every change. Returns an unsubscribe fn.\n */\nexport const onAuthChange = (listener: (state: AuthState) => void): (() => void) =>\n channel.onChange(listener);\n\n/**\n * React hook returning the current login / account state, re-rendering on\n * login / logout.\n */\nexport const useAuth = (): AuthState => channel.use();\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yBAAkC;AAClC,sBAA+C;AAuB/C,MAAM,cAAc,CAAC,MAA+B;AAClD,QAAM,IAAI;AACV,SACE,CAAC,CAAC,MACD,EAAE,WAAW,aAAa,EAAE,WAAW,eAAe,EAAE,WAAW,kBACnE,EAAE,SAAS,QAAS,OAAO,EAAE,SAAS,YAAY,OAAQ,EAAE,KAAqB,UAAU;AAEhG;AAIA,MAAM,cAAU,sCAA6B;AAAA,EAC3C,UAAU;AAAA,EACV,aAAa;AAAA,EACb,SAAS,EAAE,QAAQ,WAAW,MAAM,KAAK;AAAA,EACzC,OAAO,CAAC,QAAS,YAAY,IAAI,KAAK,IAAK,IAAI,QAAsB;AACvE,CAAC;AAMM,MAAM,eAAe,MAAiB,QAAQ,IAAI;AAMlD,MAAM,eAAe,CAAC,aAC3B,QAAQ,SAAS,QAAQ;AAMpB,MAAM,UAAU,MAAiB,QAAQ,IAAI;","names":[]}
1
+ {"version":3,"sources":["../src/auth.ts"],"sourcesContent":["import { createPushChannel } from './pushChannel';\nimport { AUTH_STATE, REQUEST_AUTH_STATE } from './generated/protocol';\n\n/**\n * Login / account state of the immediately.run user, mirrored from the host\n * window into the sandbox.\n *\n * `status` is `'unknown'` until the host has reported a value (use it to\n * distinguish \"still loading\" from a confirmed signed-out session).\n */\nexport type AuthStatus = 'unknown' | 'signed-in' | 'signed-out';\n\n/** The signed-in immediately.run user, as seen by the sandbox (no token, ever). */\nexport interface SandboxUser {\n /** GitHub login (handle) of the signed-in user. */\n login: string;\n}\n\n/** The user's login / account state: a `status` plus the `user` when signed in. */\nexport interface AuthState {\n status: AuthStatus;\n user: SandboxUser | null;\n}\n\nconst isAuthState = (v: unknown): v is AuthState => {\n const s = v as Partial<AuthState> | null;\n return (\n !!s &&\n (s.status === 'unknown' || s.status === 'signed-in' || s.status === 'signed-out') &&\n (s.user === null || (typeof s.user === 'object' && typeof (s.user as SandboxUser).login === 'string'))\n );\n};\n\n// Read over the transport (SDK_PACKAGING_SPEC §4): the host pushes `auth-state`\n// and answers `request-auth-state` (wire format: site-main channelBridge.ts).\nconst channel = createPushChannel<AuthState>({\n pushType: AUTH_STATE,\n requestType: REQUEST_AUTH_STATE,\n initial: { status: 'unknown', user: null },\n parse: (msg) => (isAuthState(msg.state) ? (msg.state as AuthState) : undefined),\n});\n\n/**\n * Returns the current login / account state. Poll this whenever you need a\n * one-off read; use {@link onAuthChange} or {@link useAuth} to react to changes.\n */\nexport const getAuthState = (): AuthState => channel.get();\n\n/**\n * Subscribe to login / logout changes. The listener is invoked immediately with\n * the current state, then again on every change. Returns an unsubscribe fn.\n */\nexport const onAuthChange = (listener: (state: AuthState) => void): (() => void) => channel.onChange(listener);\n\n/**\n * React hook returning the current login / account state, re-rendering on\n * login / logout.\n */\nexport const useAuth = (): AuthState => channel.use();\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yBAAkC;AAClC,sBAA+C;AAuB/C,MAAM,cAAc,CAAC,MAA+B;AAClD,QAAM,IAAI;AACV,SACE,CAAC,CAAC,MACD,EAAE,WAAW,aAAa,EAAE,WAAW,eAAe,EAAE,WAAW,kBACnE,EAAE,SAAS,QAAS,OAAO,EAAE,SAAS,YAAY,OAAQ,EAAE,KAAqB,UAAU;AAEhG;AAIA,MAAM,cAAU,sCAA6B;AAAA,EAC3C,UAAU;AAAA,EACV,aAAa;AAAA,EACb,SAAS,EAAE,QAAQ,WAAW,MAAM,KAAK;AAAA,EACzC,OAAO,CAAC,QAAS,YAAY,IAAI,KAAK,IAAK,IAAI,QAAsB;AACvE,CAAC;AAMM,MAAM,eAAe,MAAiB,QAAQ,IAAI;AAMlD,MAAM,eAAe,CAAC,aAAuD,QAAQ,SAAS,QAAQ;AAMtG,MAAM,UAAU,MAAiB,QAAQ,IAAI;","names":[]}
package/dist/auth.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/auth.ts"],"sourcesContent":["import { createPushChannel } from './pushChannel';\nimport { AUTH_STATE, REQUEST_AUTH_STATE } from './generated/protocol';\n\n/**\n * Login / account state of the immediately.run user, mirrored from the host\n * window into the sandbox.\n *\n * `status` is `'unknown'` until the host has reported a value (use it to\n * distinguish \"still loading\" from a confirmed signed-out session).\n */\nexport type AuthStatus = 'unknown' | 'signed-in' | 'signed-out';\n\n/** The signed-in immediately.run user, as seen by the sandbox (no token, ever). */\nexport interface SandboxUser {\n /** GitHub login (handle) of the signed-in user. */\n login: string;\n}\n\n/** The user's login / account state: a `status` plus the `user` when signed in. */\nexport interface AuthState {\n status: AuthStatus;\n user: SandboxUser | null;\n}\n\nconst isAuthState = (v: unknown): v is AuthState => {\n const s = v as Partial<AuthState> | null;\n return (\n !!s &&\n (s.status === 'unknown' || s.status === 'signed-in' || s.status === 'signed-out') &&\n (s.user === null || (typeof s.user === 'object' && typeof (s.user as SandboxUser).login === 'string'))\n );\n};\n\n// Read over the transport (SDK_PACKAGING_SPEC §4): the host pushes `auth-state`\n// and answers `request-auth-state` (wire format: site-main channelBridge.ts).\nconst channel = createPushChannel<AuthState>({\n pushType: AUTH_STATE,\n requestType: REQUEST_AUTH_STATE,\n initial: { status: 'unknown', user: null },\n parse: (msg) => (isAuthState(msg.state) ? (msg.state as AuthState) : undefined),\n});\n\n/**\n * Returns the current login / account state. Poll this whenever you need a\n * one-off read; use {@link onAuthChange} or {@link useAuth} to react to changes.\n */\nexport const getAuthState = (): AuthState => channel.get();\n\n/**\n * Subscribe to login / logout changes. The listener is invoked immediately with\n * the current state, then again on every change. Returns an unsubscribe fn.\n */\nexport const onAuthChange = (listener: (state: AuthState) => void): (() => void) =>\n channel.onChange(listener);\n\n/**\n * React hook returning the current login / account state, re-rendering on\n * login / logout.\n */\nexport const useAuth = (): AuthState => channel.use();\n"],"mappings":";AAAA,SAAS,yBAAyB;AAClC,SAAS,YAAY,0BAA0B;AAuB/C,MAAM,cAAc,CAAC,MAA+B;AAClD,QAAM,IAAI;AACV,SACE,CAAC,CAAC,MACD,EAAE,WAAW,aAAa,EAAE,WAAW,eAAe,EAAE,WAAW,kBACnE,EAAE,SAAS,QAAS,OAAO,EAAE,SAAS,YAAY,OAAQ,EAAE,KAAqB,UAAU;AAEhG;AAIA,MAAM,UAAU,kBAA6B;AAAA,EAC3C,UAAU;AAAA,EACV,aAAa;AAAA,EACb,SAAS,EAAE,QAAQ,WAAW,MAAM,KAAK;AAAA,EACzC,OAAO,CAAC,QAAS,YAAY,IAAI,KAAK,IAAK,IAAI,QAAsB;AACvE,CAAC;AAMM,MAAM,eAAe,MAAiB,QAAQ,IAAI;AAMlD,MAAM,eAAe,CAAC,aAC3B,QAAQ,SAAS,QAAQ;AAMpB,MAAM,UAAU,MAAiB,QAAQ,IAAI;","names":[]}
1
+ {"version":3,"sources":["../src/auth.ts"],"sourcesContent":["import { createPushChannel } from './pushChannel';\nimport { AUTH_STATE, REQUEST_AUTH_STATE } from './generated/protocol';\n\n/**\n * Login / account state of the immediately.run user, mirrored from the host\n * window into the sandbox.\n *\n * `status` is `'unknown'` until the host has reported a value (use it to\n * distinguish \"still loading\" from a confirmed signed-out session).\n */\nexport type AuthStatus = 'unknown' | 'signed-in' | 'signed-out';\n\n/** The signed-in immediately.run user, as seen by the sandbox (no token, ever). */\nexport interface SandboxUser {\n /** GitHub login (handle) of the signed-in user. */\n login: string;\n}\n\n/** The user's login / account state: a `status` plus the `user` when signed in. */\nexport interface AuthState {\n status: AuthStatus;\n user: SandboxUser | null;\n}\n\nconst isAuthState = (v: unknown): v is AuthState => {\n const s = v as Partial<AuthState> | null;\n return (\n !!s &&\n (s.status === 'unknown' || s.status === 'signed-in' || s.status === 'signed-out') &&\n (s.user === null || (typeof s.user === 'object' && typeof (s.user as SandboxUser).login === 'string'))\n );\n};\n\n// Read over the transport (SDK_PACKAGING_SPEC §4): the host pushes `auth-state`\n// and answers `request-auth-state` (wire format: site-main channelBridge.ts).\nconst channel = createPushChannel<AuthState>({\n pushType: AUTH_STATE,\n requestType: REQUEST_AUTH_STATE,\n initial: { status: 'unknown', user: null },\n parse: (msg) => (isAuthState(msg.state) ? (msg.state as AuthState) : undefined),\n});\n\n/**\n * Returns the current login / account state. Poll this whenever you need a\n * one-off read; use {@link onAuthChange} or {@link useAuth} to react to changes.\n */\nexport const getAuthState = (): AuthState => channel.get();\n\n/**\n * Subscribe to login / logout changes. The listener is invoked immediately with\n * the current state, then again on every change. Returns an unsubscribe fn.\n */\nexport const onAuthChange = (listener: (state: AuthState) => void): (() => void) => channel.onChange(listener);\n\n/**\n * React hook returning the current login / account state, re-rendering on\n * login / logout.\n */\nexport const useAuth = (): AuthState => channel.use();\n"],"mappings":";AAAA,SAAS,yBAAyB;AAClC,SAAS,YAAY,0BAA0B;AAuB/C,MAAM,cAAc,CAAC,MAA+B;AAClD,QAAM,IAAI;AACV,SACE,CAAC,CAAC,MACD,EAAE,WAAW,aAAa,EAAE,WAAW,eAAe,EAAE,WAAW,kBACnE,EAAE,SAAS,QAAS,OAAO,EAAE,SAAS,YAAY,OAAQ,EAAE,KAAqB,UAAU;AAEhG;AAIA,MAAM,UAAU,kBAA6B;AAAA,EAC3C,UAAU;AAAA,EACV,aAAa;AAAA,EACb,SAAS,EAAE,QAAQ,WAAW,MAAM,KAAK;AAAA,EACzC,OAAO,CAAC,QAAS,YAAY,IAAI,KAAK,IAAK,IAAI,QAAsB;AACvE,CAAC;AAMM,MAAM,eAAe,MAAiB,QAAQ,IAAI;AAMlD,MAAM,eAAe,CAAC,aAAuD,QAAQ,SAAS,QAAQ;AAMtG,MAAM,UAAU,MAAiB,QAAQ,IAAI;","names":[]}
package/dist/boot.cjs CHANGED
@@ -52,10 +52,7 @@ const updateAlreadyApplied = (filesMetadata, update) => {
52
52
  }
53
53
  return true;
54
54
  };
55
- const TinkerableApp = ({
56
- routingSpec,
57
- children
58
- }) => {
55
+ const TinkerableApp = ({ routingSpec, children }) => {
59
56
  const [context, setContext] = (0, import_react.useState)((0, import_contextUtils.getInitialContext)(routingSpec));
60
57
  (0, import_react.useEffect)(() => {
61
58
  const removeListener = (0, import_sandboxUtils.addListener)(import_protocol.URLCHANGE, ({ url }) => {
@@ -114,11 +111,7 @@ const DEFAULT_ROUTING_SPEC = {
114
111
  const CATCH_ALL_ROUTING_SPEC = {
115
112
  routes: [{ name: "AppRoot", pattern: /^.*$/, element: null }]
116
113
  };
117
- const boot = ({
118
- mdxComponents,
119
- routingSpec,
120
- children
121
- } = {}) => {
114
+ const boot = ({ mdxComponents, routingSpec, children } = {}) => {
122
115
  const rootElement = document.getElementById("root");
123
116
  if (!rootElement) {
124
117
  throw new Error("boot requires root HTML element to exist");
package/dist/boot.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/boot.tsx"],"sourcesContent":["import { FC, ReactNode, StrictMode, useEffect, useLayoutEffect, useState } from 'react';\nimport { createRoot } from 'react-dom/client';\n\nimport { emitMarkerOnce } from './markers';\n\nimport { ErrorNotFound } from './components/errors';\nimport { FileRouter } from './components/FileRouter';\nimport { MainContent } from './components/MainContent';\nimport { DEFAULT_MDX_COMPONENTS } from './components/MDXComponents';\nimport { ScrollAfterNavigation } from './components/ScrollAfterNavigation';\nimport { getInitialContext, updateContext } from './contextUtils';\nimport { getInjectedMetadataEmitter, resolveMetadataSource } from './injectedBundler';\nimport { MDXProvider } from './MDXProvider';\nimport { ModuleCache, ModuleCacheContextProvider } from './moduleCache';\nimport { Router } from './routing';\nimport type { RoutingSpec } from './RoutingSpec';\nimport { FilesMetadata } from './sandboxTypes';\nimport { addListener } from './sandboxUtils';\nimport { TinkerableContext, TinkerableState } from './TinkerableContext';\nimport { FILES_PREFIX } from './urlUtils';\nimport { METADATA_UPDATE, URLCHANGE } from './generated/protocol';\n\n/** A map of MDX component overrides, or a function that receives the platform\n * {@link DEFAULT_MDX_COMPONENTS} and returns the full map to use. */\nexport type MdxComponents =\n | Record<string, FC>\n | ((defaults: Record<string, FC>) => Record<string, FC>);\n\n/**\n * Resolve the effective MDX component map from a {@link BootProps.mdxComponents}\n * value (MARKDOWN_SYNTAX_SPEC §11.3):\n * - `undefined` → the platform {@link DEFAULT_MDX_COMPONENTS} (same reference).\n * - a **function** → the full-replace escape hatch, handed the defaults.\n * - a **map** → merged *over* the defaults (`{ ...defaults, ...map }`), so\n * overriding one component keeps the rest — the phantom-defaults invariant\n * (§11.2) that stops the MDX missing-reference guard from firing.\n */\nexport const resolveMdxComponents = (mdxComponents?: MdxComponents): Record<string, FC> =>\n mdxComponents === undefined\n ? (DEFAULT_MDX_COMPONENTS as Record<string, FC>)\n : typeof mdxComponents === 'function'\n ? mdxComponents(DEFAULT_MDX_COMPONENTS as Record<string, FC>)\n : { ...(DEFAULT_MDX_COMPONENTS as Record<string, FC>), ...mdxComponents };\n\n/** Options for {@link boot}: MDX overrides, a route table, or an app root. */\nexport type BootProps = {\n /**\n * MDX component overrides. A **map** is *merged over* the platform defaults\n * ({@link DEFAULT_MDX_COMPONENTS}) — so overriding `WikiLink` alone keeps the\n * default `a` and `Admonition` (MARKDOWN_SYNTAX_SPEC §11.3). Pass a **function**\n * `(defaults) => map` as the full-replace escape hatch when you want complete\n * control over the set.\n */\n mdxComponents?: MdxComponents;\n routingSpec?: RoutingSpec;\n /**\n * App root rendered directly inside the providers (with full navigation\n * context), instead of dispatching through a `routingSpec`. Render\n * `<Routes>`/`<Route>` here for fully dynamic routing — no catch-all rule\n * boilerplate. Takes precedence over `routingSpec` for what is rendered.\n */\n children?: ReactNode;\n};\n\nconst updateAlreadyApplied = (filesMetadata: FilesMetadata, update: FilesMetadata) => {\n for (let [key, value] of Object.entries(update)) {\n if (filesMetadata[key] !== value) {\n return false;\n }\n }\n return true;\n};\n\n/** The app shell {@link boot} renders: holds navigation state, subscribes to host\n * URL + metadata pushes, and renders `children` or the route `<Router />`. */\nexport const TinkerableApp = ({\n routingSpec,\n children,\n}: {\n routingSpec: RoutingSpec;\n children?: ReactNode;\n}) => {\n const [context, setContext] = useState<TinkerableState>(getInitialContext(routingSpec));\n useEffect(() => {\n const removeListener = addListener(URLCHANGE, ({ url }) => {\n setContext((context) => {\n const updatedContext = updateContext(context, url);\n if (updatedContext !== context) {\n console.log(\n `[Sandbox] Updating path from ${context.navigationState.sandboxPath} to ${updatedContext.navigationState.sandboxPath}`\n );\n }\n return updatedContext;\n });\n });\n return removeListener;\n }, [setContext]);\n useEffect(() => {\n // Phase 5 dual-mode (SDK_PACKAGING_SPEC §4/§8): prefer the injected bundler's\n // metadata emitter (the live path, byte-identical); when the SDK is npm-fetched\n // with no injection, `event` is undefined so `addListener` receives\n // 'metadata-update' over the §4 transport instead, and `enable` is a no-op.\n const source = resolveMetadataSource(getInjectedMetadataEmitter());\n const dispose = addListener(\n METADATA_UPDATE,\n ({ update }: Record<string, any>) => {\n setContext((prevContext) =>\n updateAlreadyApplied(prevContext.filesMetadata, update)\n ? prevContext\n : {\n ...prevContext,\n filesMetadata: {\n // TODO: file deletion!\n ...prevContext.filesMetadata,\n ...update,\n },\n }\n );\n },\n source.event\n );\n source.enable();\n return dispose;\n }, [setContext]);\n\n return (\n <TinkerableContext value={context}>\n {/* Capability C: lands cross-page `#fragment` deep-links on their section\n after the destination tree mounts, uniform for every MDX app (§13.5). */}\n <ScrollAfterNavigation />\n {children ?? <Router />}\n </TinkerableContext>\n );\n};\n\n// Boot marker emitter (LOAD_PROFILING_SPEC §3, R3-46). Rendered at the top of the\n// app tree so its layout effect fires on the FIRST root-render commit: that instant\n// is `ir.fmp` (the content is in the DOM, about to paint) and the baseline for\n// `ir.interactive` (the host treats a forwarded `ir.interactive` as the root-commit\n// signal and resolves `max(commit, reportReady)` — LP2-3 — so this can only ever be\n// delayed by an app's `reportReady()`, never advanced). Emitted in canonical stream\n// order (fmp then interactive); idempotent per name (StrictMode-safe). Renders null.\nconst BootMarkers = (): null => {\n useLayoutEffect(() => {\n emitMarkerOnce('ir.fmp');\n emitMarkerOnce('ir.interactive');\n }, []);\n return null;\n};\n\n/** The default route table when `boot` is called with no `routingSpec`/`children`:\n * `/` → main content, `/files/<path>` → the file router, else not-found.\n * Re-expressed with path templates (SANDBOX_ROUTING_SPEC §7); the file path\n * surfaces under the `*` wildcard. The catch-all stays a raw RegExp — the\n * escape hatch — so it anchors `.+` (a non-empty path) exactly as before. */\nexport const DEFAULT_ROUTING_SPEC: RoutingSpec = {\n routes: [\n { name: 'MainContent', pattern: '/', element: <MainContent /> },\n { name: 'FileRouter', pattern: `${FILES_PREFIX}/*`, element: <FileRouter /> },\n { name: 'ErrorNotFound', pattern: /^(?<path>.+)$/, element: <ErrorNotFound /> },\n ],\n};\n\n/**\n * Matches any `sandboxPath` so navigation context can be built without a route\n * table. Used when {@link boot} is given `children` (the app owns dispatch via\n * `<Routes>`); the catch-all's `element` is never rendered (children are).\n */\nexport const CATCH_ALL_ROUTING_SPEC: RoutingSpec = {\n routes: [{ name: 'AppRoot', pattern: /^.*$/, element: null }],\n};\n\n/**\n * Mount an immediately.run app into the sandbox `#root`. The entry point every\n * app calls from `index.tsx`: wires the MDX, module-cache, and navigation\n * providers, then renders the route table (`routingSpec`) or your `children`.\n */\nexport const boot = ({\n mdxComponents,\n routingSpec,\n children,\n}: BootProps = {}) => {\n const rootElement = document.getElementById('root');\n if (!rootElement) {\n throw new Error('boot requires root HTML element to exist');\n }\n const resolvedComponents = resolveMdxComponents(mdxComponents);\n // `children` own dispatch, so a catch-all keeps navigation working without a\n // table; otherwise fall back to the default file/main-content routes.\n const spec = routingSpec ?? (children ? CATCH_ALL_ROUTING_SPEC : DEFAULT_ROUTING_SPEC);\n const moduleCache = new ModuleCache();\n const root = createRoot(rootElement);\n root.render(\n <StrictMode>\n <ModuleCacheContextProvider moduleCache={moduleCache}>\n <MDXProvider components={resolvedComponents}>\n <BootMarkers />\n <TinkerableApp routingSpec={spec}>{children}</TinkerableApp>\n </MDXProvider>\n </ModuleCacheContextProvider>\n </StrictMode>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA8HI;AA9HJ,mBAAgF;AAChF,oBAA2B;AAE3B,qBAA+B;AAE/B,oBAA8B;AAC9B,wBAA2B;AAC3B,yBAA4B;AAC5B,2BAAuC;AACvC,mCAAsC;AACtC,0BAAiD;AACjD,6BAAkE;AAClE,yBAA4B;AAC5B,yBAAwD;AACxD,qBAAuB;AAGvB,0BAA4B;AAC5B,+BAAmD;AACnD,sBAA6B;AAC7B,sBAA2C;AAiBpC,MAAM,uBAAuB,CAAC,kBACnC,kBAAkB,SACb,8CACD,OAAO,kBAAkB,aACvB,cAAc,2CAA4C,IAC1D,EAAE,GAAI,6CAA+C,GAAG,cAAc;AAsB9E,MAAM,uBAAuB,CAAC,eAA8B,WAA0B;AACpF,WAAS,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AAC/C,QAAI,cAAc,GAAG,MAAM,OAAO;AAChC,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAIO,MAAM,gBAAgB,CAAC;AAAA,EAC5B;AAAA,EACA;AACF,MAGM;AACJ,QAAM,CAAC,SAAS,UAAU,QAAI,2BAA0B,uCAAkB,WAAW,CAAC;AACtF,8BAAU,MAAM;AACd,UAAM,qBAAiB,iCAAY,2BAAW,CAAC,EAAE,IAAI,MAAM;AACzD,iBAAW,CAACA,aAAY;AACtB,cAAM,qBAAiB,mCAAcA,UAAS,GAAG;AACjD,YAAI,mBAAmBA,UAAS;AAC9B,kBAAQ;AAAA,YACN,gCAAgCA,SAAQ,gBAAgB,WAAW,OAAO,eAAe,gBAAgB,WAAW;AAAA,UACtH;AAAA,QACF;AACA,eAAO;AAAA,MACT,CAAC;AAAA,IACH,CAAC;AACD,WAAO;AAAA,EACT,GAAG,CAAC,UAAU,CAAC;AACf,8BAAU,MAAM;AAKd,UAAM,aAAS,kDAAsB,mDAA2B,CAAC;AACjE,UAAM,cAAU;AAAA,MACd;AAAA,MACA,CAAC,EAAE,OAAO,MAA2B;AACnC;AAAA,UAAW,CAAC,gBACV,qBAAqB,YAAY,eAAe,MAAM,IAClD,cACA;AAAA,YACE,GAAG;AAAA,YACH,eAAe;AAAA;AAAA,cAEb,GAAG,YAAY;AAAA,cACf,GAAG;AAAA,YACL;AAAA,UACF;AAAA,QACN;AAAA,MACF;AAAA,MACA,OAAO;AAAA,IACT;AACA,WAAO,OAAO;AACd,WAAO;AAAA,EACT,GAAG,CAAC,UAAU,CAAC;AAEf,SACE,6CAAC,8CAAkB,OAAO,SAGxB;AAAA,gDAAC,sDAAsB;AAAA,IACtB,YAAY,4CAAC,yBAAO;AAAA,KACvB;AAEJ;AASA,MAAM,cAAc,MAAY;AAC9B,oCAAgB,MAAM;AACpB,uCAAe,QAAQ;AACvB,uCAAe,gBAAgB;AAAA,EACjC,GAAG,CAAC,CAAC;AACL,SAAO;AACT;AAOO,MAAM,uBAAoC;AAAA,EAC/C,QAAQ;AAAA,IACN,EAAE,MAAM,eAAe,SAAS,KAAK,SAAS,4CAAC,kCAAY,EAAG;AAAA,IAC9D,EAAE,MAAM,cAAc,SAAS,GAAG,4BAAY,MAAM,SAAS,4CAAC,gCAAW,EAAG;AAAA,IAC5E,EAAE,MAAM,iBAAiB,SAAS,iBAAiB,SAAS,4CAAC,+BAAc,EAAG;AAAA,EAChF;AACF;AAOO,MAAM,yBAAsC;AAAA,EACjD,QAAQ,CAAC,EAAE,MAAM,WAAW,SAAS,QAAQ,SAAS,KAAK,CAAC;AAC9D;AAOO,MAAM,OAAO,CAAC;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AACF,IAAe,CAAC,MAAM;AACpB,QAAM,cAAc,SAAS,eAAe,MAAM;AAClD,MAAI,CAAC,aAAa;AAChB,UAAM,IAAI,MAAM,0CAA0C;AAAA,EAC5D;AACA,QAAM,qBAAqB,qBAAqB,aAAa;AAG7D,QAAM,OAAO,gBAAgB,WAAW,yBAAyB;AACjE,QAAM,cAAc,IAAI,+BAAY;AACpC,QAAM,WAAO,0BAAW,WAAW;AACnC,OAAK;AAAA,IACH,4CAAC,2BACC,sDAAC,iDAA2B,aAC1B,uDAAC,kCAAY,YAAY,oBACvB;AAAA,kDAAC,eAAY;AAAA,MACb,4CAAC,iBAAc,aAAa,MAAO,UAAS;AAAA,OAC9C,GACF,GACF;AAAA,EACF;AACF;","names":["context"]}
1
+ {"version":3,"sources":["../src/boot.tsx"],"sourcesContent":["import { FC, ReactNode, StrictMode, useEffect, useLayoutEffect, useState } from 'react';\nimport { createRoot } from 'react-dom/client';\n\nimport { emitMarkerOnce } from './markers';\n\nimport { ErrorNotFound } from './components/errors';\nimport { FileRouter } from './components/FileRouter';\nimport { MainContent } from './components/MainContent';\nimport { DEFAULT_MDX_COMPONENTS } from './components/MDXComponents';\nimport { ScrollAfterNavigation } from './components/ScrollAfterNavigation';\nimport { getInitialContext, updateContext } from './contextUtils';\nimport { getInjectedMetadataEmitter, resolveMetadataSource } from './injectedBundler';\nimport { MDXProvider } from './MDXProvider';\nimport { ModuleCache, ModuleCacheContextProvider } from './moduleCache';\nimport { Router } from './routing';\nimport type { RoutingSpec } from './RoutingSpec';\nimport { FilesMetadata } from './sandboxTypes';\nimport { addListener } from './sandboxUtils';\nimport { TinkerableContext, TinkerableState } from './TinkerableContext';\nimport { FILES_PREFIX } from './urlUtils';\nimport { METADATA_UPDATE, URLCHANGE } from './generated/protocol';\n\n/** A map of MDX component overrides, or a function that receives the platform\n * {@link DEFAULT_MDX_COMPONENTS} and returns the full map to use. */\nexport type MdxComponents = Record<string, FC> | ((defaults: Record<string, FC>) => Record<string, FC>);\n\n/**\n * Resolve the effective MDX component map from a {@link BootProps.mdxComponents}\n * value (MARKDOWN_SYNTAX_SPEC §11.3):\n * - `undefined` → the platform {@link DEFAULT_MDX_COMPONENTS} (same reference).\n * - a **function** → the full-replace escape hatch, handed the defaults.\n * - a **map** → merged *over* the defaults (`{ ...defaults, ...map }`), so\n * overriding one component keeps the rest — the phantom-defaults invariant\n * (§11.2) that stops the MDX missing-reference guard from firing.\n */\nexport const resolveMdxComponents = (mdxComponents?: MdxComponents): Record<string, FC> =>\n mdxComponents === undefined\n ? (DEFAULT_MDX_COMPONENTS as Record<string, FC>)\n : typeof mdxComponents === 'function'\n ? mdxComponents(DEFAULT_MDX_COMPONENTS as Record<string, FC>)\n : { ...(DEFAULT_MDX_COMPONENTS as Record<string, FC>), ...mdxComponents };\n\n/** Options for {@link boot}: MDX overrides, a route table, or an app root. */\nexport type BootProps = {\n /**\n * MDX component overrides. A **map** is *merged over* the platform defaults\n * ({@link DEFAULT_MDX_COMPONENTS}) — so overriding `WikiLink` alone keeps the\n * default `a` and `Admonition` (MARKDOWN_SYNTAX_SPEC §11.3). Pass a **function**\n * `(defaults) => map` as the full-replace escape hatch when you want complete\n * control over the set.\n */\n mdxComponents?: MdxComponents;\n routingSpec?: RoutingSpec;\n /**\n * App root rendered directly inside the providers (with full navigation\n * context), instead of dispatching through a `routingSpec`. Render\n * `<Routes>`/`<Route>` here for fully dynamic routing — no catch-all rule\n * boilerplate. Takes precedence over `routingSpec` for what is rendered.\n */\n children?: ReactNode;\n};\n\nconst updateAlreadyApplied = (filesMetadata: FilesMetadata, update: FilesMetadata) => {\n for (let [key, value] of Object.entries(update)) {\n if (filesMetadata[key] !== value) {\n return false;\n }\n }\n return true;\n};\n\n/** The app shell {@link boot} renders: holds navigation state, subscribes to host\n * URL + metadata pushes, and renders `children` or the route `<Router />`. */\nexport const TinkerableApp = ({ routingSpec, children }: { routingSpec: RoutingSpec; children?: ReactNode }) => {\n const [context, setContext] = useState<TinkerableState>(getInitialContext(routingSpec));\n useEffect(() => {\n const removeListener = addListener(URLCHANGE, ({ url }) => {\n setContext((context) => {\n const updatedContext = updateContext(context, url);\n if (updatedContext !== context) {\n console.log(\n `[Sandbox] Updating path from ${context.navigationState.sandboxPath} to ${updatedContext.navigationState.sandboxPath}`,\n );\n }\n return updatedContext;\n });\n });\n return removeListener;\n }, [setContext]);\n useEffect(() => {\n // Phase 5 dual-mode (SDK_PACKAGING_SPEC §4/§8): prefer the injected bundler's\n // metadata emitter (the live path, byte-identical); when the SDK is npm-fetched\n // with no injection, `event` is undefined so `addListener` receives\n // 'metadata-update' over the §4 transport instead, and `enable` is a no-op.\n const source = resolveMetadataSource(getInjectedMetadataEmitter());\n const dispose = addListener(\n METADATA_UPDATE,\n ({ update }: Record<string, any>) => {\n setContext((prevContext) =>\n updateAlreadyApplied(prevContext.filesMetadata, update)\n ? prevContext\n : {\n ...prevContext,\n filesMetadata: {\n // TODO: file deletion!\n ...prevContext.filesMetadata,\n ...update,\n },\n },\n );\n },\n source.event,\n );\n source.enable();\n return dispose;\n }, [setContext]);\n\n return (\n <TinkerableContext value={context}>\n {/* Capability C: lands cross-page `#fragment` deep-links on their section\n after the destination tree mounts, uniform for every MDX app (§13.5). */}\n <ScrollAfterNavigation />\n {children ?? <Router />}\n </TinkerableContext>\n );\n};\n\n// Boot marker emitter (LOAD_PROFILING_SPEC §3, R3-46). Rendered at the top of the\n// app tree so its layout effect fires on the FIRST root-render commit: that instant\n// is `ir.fmp` (the content is in the DOM, about to paint) and the baseline for\n// `ir.interactive` (the host treats a forwarded `ir.interactive` as the root-commit\n// signal and resolves `max(commit, reportReady)` — LP2-3 — so this can only ever be\n// delayed by an app's `reportReady()`, never advanced). Emitted in canonical stream\n// order (fmp then interactive); idempotent per name (StrictMode-safe). Renders null.\nconst BootMarkers = (): null => {\n useLayoutEffect(() => {\n emitMarkerOnce('ir.fmp');\n emitMarkerOnce('ir.interactive');\n }, []);\n return null;\n};\n\n/** The default route table when `boot` is called with no `routingSpec`/`children`:\n * `/` → main content, `/files/<path>` → the file router, else not-found.\n * Re-expressed with path templates (SANDBOX_ROUTING_SPEC §7); the file path\n * surfaces under the `*` wildcard. The catch-all stays a raw RegExp — the\n * escape hatch — so it anchors `.+` (a non-empty path) exactly as before. */\nexport const DEFAULT_ROUTING_SPEC: RoutingSpec = {\n routes: [\n { name: 'MainContent', pattern: '/', element: <MainContent /> },\n { name: 'FileRouter', pattern: `${FILES_PREFIX}/*`, element: <FileRouter /> },\n { name: 'ErrorNotFound', pattern: /^(?<path>.+)$/, element: <ErrorNotFound /> },\n ],\n};\n\n/**\n * Matches any `sandboxPath` so navigation context can be built without a route\n * table. Used when {@link boot} is given `children` (the app owns dispatch via\n * `<Routes>`); the catch-all's `element` is never rendered (children are).\n */\nexport const CATCH_ALL_ROUTING_SPEC: RoutingSpec = {\n routes: [{ name: 'AppRoot', pattern: /^.*$/, element: null }],\n};\n\n/**\n * Mount an immediately.run app into the sandbox `#root`. The entry point every\n * app calls from `index.tsx`: wires the MDX, module-cache, and navigation\n * providers, then renders the route table (`routingSpec`) or your `children`.\n */\nexport const boot = ({ mdxComponents, routingSpec, children }: BootProps = {}) => {\n const rootElement = document.getElementById('root');\n if (!rootElement) {\n throw new Error('boot requires root HTML element to exist');\n }\n const resolvedComponents = resolveMdxComponents(mdxComponents);\n // `children` own dispatch, so a catch-all keeps navigation working without a\n // table; otherwise fall back to the default file/main-content routes.\n const spec = routingSpec ?? (children ? CATCH_ALL_ROUTING_SPEC : DEFAULT_ROUTING_SPEC);\n const moduleCache = new ModuleCache();\n const root = createRoot(rootElement);\n root.render(\n <StrictMode>\n <ModuleCacheContextProvider moduleCache={moduleCache}>\n <MDXProvider components={resolvedComponents}>\n <BootMarkers />\n <TinkerableApp routingSpec={spec}>{children}</TinkerableApp>\n </MDXProvider>\n </ModuleCacheContextProvider>\n </StrictMode>,\n );\n};\n"],"mappings":"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","names":["context"]}
package/dist/boot.d.cts CHANGED
@@ -36,7 +36,7 @@ type BootProps = {
36
36
  };
37
37
  /** The app shell {@link boot} renders: holds navigation state, subscribes to host
38
38
  * URL + metadata pushes, and renders `children` or the route `<Router />`. */
39
- declare const TinkerableApp: ({ routingSpec, children, }: {
39
+ declare const TinkerableApp: ({ routingSpec, children }: {
40
40
  routingSpec: RoutingSpec;
41
41
  children?: ReactNode;
42
42
  }) => react.JSX.Element;
@@ -57,6 +57,6 @@ declare const CATCH_ALL_ROUTING_SPEC: RoutingSpec;
57
57
  * app calls from `index.tsx`: wires the MDX, module-cache, and navigation
58
58
  * providers, then renders the route table (`routingSpec`) or your `children`.
59
59
  */
60
- declare const boot: ({ mdxComponents, routingSpec, children, }?: BootProps) => void;
60
+ declare const boot: ({ mdxComponents, routingSpec, children }?: BootProps) => void;
61
61
 
62
62
  export { type BootProps, CATCH_ALL_ROUTING_SPEC, DEFAULT_ROUTING_SPEC, type MdxComponents, TinkerableApp, boot, resolveMdxComponents };
package/dist/boot.d.ts CHANGED
@@ -36,7 +36,7 @@ type BootProps = {
36
36
  };
37
37
  /** The app shell {@link boot} renders: holds navigation state, subscribes to host
38
38
  * URL + metadata pushes, and renders `children` or the route `<Router />`. */
39
- declare const TinkerableApp: ({ routingSpec, children, }: {
39
+ declare const TinkerableApp: ({ routingSpec, children }: {
40
40
  routingSpec: RoutingSpec;
41
41
  children?: ReactNode;
42
42
  }) => react.JSX.Element;
@@ -57,6 +57,6 @@ declare const CATCH_ALL_ROUTING_SPEC: RoutingSpec;
57
57
  * app calls from `index.tsx`: wires the MDX, module-cache, and navigation
58
58
  * providers, then renders the route table (`routingSpec`) or your `children`.
59
59
  */
60
- declare const boot: ({ mdxComponents, routingSpec, children, }?: BootProps) => void;
60
+ declare const boot: ({ mdxComponents, routingSpec, children }?: BootProps) => void;
61
61
 
62
62
  export { type BootProps, CATCH_ALL_ROUTING_SPEC, DEFAULT_ROUTING_SPEC, type MdxComponents, TinkerableApp, boot, resolveMdxComponents };
package/dist/boot.js CHANGED
@@ -26,10 +26,7 @@ const updateAlreadyApplied = (filesMetadata, update) => {
26
26
  }
27
27
  return true;
28
28
  };
29
- const TinkerableApp = ({
30
- routingSpec,
31
- children
32
- }) => {
29
+ const TinkerableApp = ({ routingSpec, children }) => {
33
30
  const [context, setContext] = useState(getInitialContext(routingSpec));
34
31
  useEffect(() => {
35
32
  const removeListener = addListener(URLCHANGE, ({ url }) => {
@@ -88,11 +85,7 @@ const DEFAULT_ROUTING_SPEC = {
88
85
  const CATCH_ALL_ROUTING_SPEC = {
89
86
  routes: [{ name: "AppRoot", pattern: /^.*$/, element: null }]
90
87
  };
91
- const boot = ({
92
- mdxComponents,
93
- routingSpec,
94
- children
95
- } = {}) => {
88
+ const boot = ({ mdxComponents, routingSpec, children } = {}) => {
96
89
  const rootElement = document.getElementById("root");
97
90
  if (!rootElement) {
98
91
  throw new Error("boot requires root HTML element to exist");
package/dist/boot.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/boot.tsx"],"sourcesContent":["import { FC, ReactNode, StrictMode, useEffect, useLayoutEffect, useState } from 'react';\nimport { createRoot } from 'react-dom/client';\n\nimport { emitMarkerOnce } from './markers';\n\nimport { ErrorNotFound } from './components/errors';\nimport { FileRouter } from './components/FileRouter';\nimport { MainContent } from './components/MainContent';\nimport { DEFAULT_MDX_COMPONENTS } from './components/MDXComponents';\nimport { ScrollAfterNavigation } from './components/ScrollAfterNavigation';\nimport { getInitialContext, updateContext } from './contextUtils';\nimport { getInjectedMetadataEmitter, resolveMetadataSource } from './injectedBundler';\nimport { MDXProvider } from './MDXProvider';\nimport { ModuleCache, ModuleCacheContextProvider } from './moduleCache';\nimport { Router } from './routing';\nimport type { RoutingSpec } from './RoutingSpec';\nimport { FilesMetadata } from './sandboxTypes';\nimport { addListener } from './sandboxUtils';\nimport { TinkerableContext, TinkerableState } from './TinkerableContext';\nimport { FILES_PREFIX } from './urlUtils';\nimport { METADATA_UPDATE, URLCHANGE } from './generated/protocol';\n\n/** A map of MDX component overrides, or a function that receives the platform\n * {@link DEFAULT_MDX_COMPONENTS} and returns the full map to use. */\nexport type MdxComponents =\n | Record<string, FC>\n | ((defaults: Record<string, FC>) => Record<string, FC>);\n\n/**\n * Resolve the effective MDX component map from a {@link BootProps.mdxComponents}\n * value (MARKDOWN_SYNTAX_SPEC §11.3):\n * - `undefined` → the platform {@link DEFAULT_MDX_COMPONENTS} (same reference).\n * - a **function** → the full-replace escape hatch, handed the defaults.\n * - a **map** → merged *over* the defaults (`{ ...defaults, ...map }`), so\n * overriding one component keeps the rest — the phantom-defaults invariant\n * (§11.2) that stops the MDX missing-reference guard from firing.\n */\nexport const resolveMdxComponents = (mdxComponents?: MdxComponents): Record<string, FC> =>\n mdxComponents === undefined\n ? (DEFAULT_MDX_COMPONENTS as Record<string, FC>)\n : typeof mdxComponents === 'function'\n ? mdxComponents(DEFAULT_MDX_COMPONENTS as Record<string, FC>)\n : { ...(DEFAULT_MDX_COMPONENTS as Record<string, FC>), ...mdxComponents };\n\n/** Options for {@link boot}: MDX overrides, a route table, or an app root. */\nexport type BootProps = {\n /**\n * MDX component overrides. A **map** is *merged over* the platform defaults\n * ({@link DEFAULT_MDX_COMPONENTS}) — so overriding `WikiLink` alone keeps the\n * default `a` and `Admonition` (MARKDOWN_SYNTAX_SPEC §11.3). Pass a **function**\n * `(defaults) => map` as the full-replace escape hatch when you want complete\n * control over the set.\n */\n mdxComponents?: MdxComponents;\n routingSpec?: RoutingSpec;\n /**\n * App root rendered directly inside the providers (with full navigation\n * context), instead of dispatching through a `routingSpec`. Render\n * `<Routes>`/`<Route>` here for fully dynamic routing — no catch-all rule\n * boilerplate. Takes precedence over `routingSpec` for what is rendered.\n */\n children?: ReactNode;\n};\n\nconst updateAlreadyApplied = (filesMetadata: FilesMetadata, update: FilesMetadata) => {\n for (let [key, value] of Object.entries(update)) {\n if (filesMetadata[key] !== value) {\n return false;\n }\n }\n return true;\n};\n\n/** The app shell {@link boot} renders: holds navigation state, subscribes to host\n * URL + metadata pushes, and renders `children` or the route `<Router />`. */\nexport const TinkerableApp = ({\n routingSpec,\n children,\n}: {\n routingSpec: RoutingSpec;\n children?: ReactNode;\n}) => {\n const [context, setContext] = useState<TinkerableState>(getInitialContext(routingSpec));\n useEffect(() => {\n const removeListener = addListener(URLCHANGE, ({ url }) => {\n setContext((context) => {\n const updatedContext = updateContext(context, url);\n if (updatedContext !== context) {\n console.log(\n `[Sandbox] Updating path from ${context.navigationState.sandboxPath} to ${updatedContext.navigationState.sandboxPath}`\n );\n }\n return updatedContext;\n });\n });\n return removeListener;\n }, [setContext]);\n useEffect(() => {\n // Phase 5 dual-mode (SDK_PACKAGING_SPEC §4/§8): prefer the injected bundler's\n // metadata emitter (the live path, byte-identical); when the SDK is npm-fetched\n // with no injection, `event` is undefined so `addListener` receives\n // 'metadata-update' over the §4 transport instead, and `enable` is a no-op.\n const source = resolveMetadataSource(getInjectedMetadataEmitter());\n const dispose = addListener(\n METADATA_UPDATE,\n ({ update }: Record<string, any>) => {\n setContext((prevContext) =>\n updateAlreadyApplied(prevContext.filesMetadata, update)\n ? prevContext\n : {\n ...prevContext,\n filesMetadata: {\n // TODO: file deletion!\n ...prevContext.filesMetadata,\n ...update,\n },\n }\n );\n },\n source.event\n );\n source.enable();\n return dispose;\n }, [setContext]);\n\n return (\n <TinkerableContext value={context}>\n {/* Capability C: lands cross-page `#fragment` deep-links on their section\n after the destination tree mounts, uniform for every MDX app (§13.5). */}\n <ScrollAfterNavigation />\n {children ?? <Router />}\n </TinkerableContext>\n );\n};\n\n// Boot marker emitter (LOAD_PROFILING_SPEC §3, R3-46). Rendered at the top of the\n// app tree so its layout effect fires on the FIRST root-render commit: that instant\n// is `ir.fmp` (the content is in the DOM, about to paint) and the baseline for\n// `ir.interactive` (the host treats a forwarded `ir.interactive` as the root-commit\n// signal and resolves `max(commit, reportReady)` — LP2-3 — so this can only ever be\n// delayed by an app's `reportReady()`, never advanced). Emitted in canonical stream\n// order (fmp then interactive); idempotent per name (StrictMode-safe). Renders null.\nconst BootMarkers = (): null => {\n useLayoutEffect(() => {\n emitMarkerOnce('ir.fmp');\n emitMarkerOnce('ir.interactive');\n }, []);\n return null;\n};\n\n/** The default route table when `boot` is called with no `routingSpec`/`children`:\n * `/` → main content, `/files/<path>` → the file router, else not-found.\n * Re-expressed with path templates (SANDBOX_ROUTING_SPEC §7); the file path\n * surfaces under the `*` wildcard. The catch-all stays a raw RegExp — the\n * escape hatch — so it anchors `.+` (a non-empty path) exactly as before. */\nexport const DEFAULT_ROUTING_SPEC: RoutingSpec = {\n routes: [\n { name: 'MainContent', pattern: '/', element: <MainContent /> },\n { name: 'FileRouter', pattern: `${FILES_PREFIX}/*`, element: <FileRouter /> },\n { name: 'ErrorNotFound', pattern: /^(?<path>.+)$/, element: <ErrorNotFound /> },\n ],\n};\n\n/**\n * Matches any `sandboxPath` so navigation context can be built without a route\n * table. Used when {@link boot} is given `children` (the app owns dispatch via\n * `<Routes>`); the catch-all's `element` is never rendered (children are).\n */\nexport const CATCH_ALL_ROUTING_SPEC: RoutingSpec = {\n routes: [{ name: 'AppRoot', pattern: /^.*$/, element: null }],\n};\n\n/**\n * Mount an immediately.run app into the sandbox `#root`. The entry point every\n * app calls from `index.tsx`: wires the MDX, module-cache, and navigation\n * providers, then renders the route table (`routingSpec`) or your `children`.\n */\nexport const boot = ({\n mdxComponents,\n routingSpec,\n children,\n}: BootProps = {}) => {\n const rootElement = document.getElementById('root');\n if (!rootElement) {\n throw new Error('boot requires root HTML element to exist');\n }\n const resolvedComponents = resolveMdxComponents(mdxComponents);\n // `children` own dispatch, so a catch-all keeps navigation working without a\n // table; otherwise fall back to the default file/main-content routes.\n const spec = routingSpec ?? (children ? CATCH_ALL_ROUTING_SPEC : DEFAULT_ROUTING_SPEC);\n const moduleCache = new ModuleCache();\n const root = createRoot(rootElement);\n root.render(\n <StrictMode>\n <ModuleCacheContextProvider moduleCache={moduleCache}>\n <MDXProvider components={resolvedComponents}>\n <BootMarkers />\n <TinkerableApp routingSpec={spec}>{children}</TinkerableApp>\n </MDXProvider>\n </ModuleCacheContextProvider>\n </StrictMode>\n );\n};\n"],"mappings":"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","names":["context"]}
1
+ {"version":3,"sources":["../src/boot.tsx"],"sourcesContent":["import { FC, ReactNode, StrictMode, useEffect, useLayoutEffect, useState } from 'react';\nimport { createRoot } from 'react-dom/client';\n\nimport { emitMarkerOnce } from './markers';\n\nimport { ErrorNotFound } from './components/errors';\nimport { FileRouter } from './components/FileRouter';\nimport { MainContent } from './components/MainContent';\nimport { DEFAULT_MDX_COMPONENTS } from './components/MDXComponents';\nimport { ScrollAfterNavigation } from './components/ScrollAfterNavigation';\nimport { getInitialContext, updateContext } from './contextUtils';\nimport { getInjectedMetadataEmitter, resolveMetadataSource } from './injectedBundler';\nimport { MDXProvider } from './MDXProvider';\nimport { ModuleCache, ModuleCacheContextProvider } from './moduleCache';\nimport { Router } from './routing';\nimport type { RoutingSpec } from './RoutingSpec';\nimport { FilesMetadata } from './sandboxTypes';\nimport { addListener } from './sandboxUtils';\nimport { TinkerableContext, TinkerableState } from './TinkerableContext';\nimport { FILES_PREFIX } from './urlUtils';\nimport { METADATA_UPDATE, URLCHANGE } from './generated/protocol';\n\n/** A map of MDX component overrides, or a function that receives the platform\n * {@link DEFAULT_MDX_COMPONENTS} and returns the full map to use. */\nexport type MdxComponents = Record<string, FC> | ((defaults: Record<string, FC>) => Record<string, FC>);\n\n/**\n * Resolve the effective MDX component map from a {@link BootProps.mdxComponents}\n * value (MARKDOWN_SYNTAX_SPEC §11.3):\n * - `undefined` → the platform {@link DEFAULT_MDX_COMPONENTS} (same reference).\n * - a **function** → the full-replace escape hatch, handed the defaults.\n * - a **map** → merged *over* the defaults (`{ ...defaults, ...map }`), so\n * overriding one component keeps the rest — the phantom-defaults invariant\n * (§11.2) that stops the MDX missing-reference guard from firing.\n */\nexport const resolveMdxComponents = (mdxComponents?: MdxComponents): Record<string, FC> =>\n mdxComponents === undefined\n ? (DEFAULT_MDX_COMPONENTS as Record<string, FC>)\n : typeof mdxComponents === 'function'\n ? mdxComponents(DEFAULT_MDX_COMPONENTS as Record<string, FC>)\n : { ...(DEFAULT_MDX_COMPONENTS as Record<string, FC>), ...mdxComponents };\n\n/** Options for {@link boot}: MDX overrides, a route table, or an app root. */\nexport type BootProps = {\n /**\n * MDX component overrides. A **map** is *merged over* the platform defaults\n * ({@link DEFAULT_MDX_COMPONENTS}) — so overriding `WikiLink` alone keeps the\n * default `a` and `Admonition` (MARKDOWN_SYNTAX_SPEC §11.3). Pass a **function**\n * `(defaults) => map` as the full-replace escape hatch when you want complete\n * control over the set.\n */\n mdxComponents?: MdxComponents;\n routingSpec?: RoutingSpec;\n /**\n * App root rendered directly inside the providers (with full navigation\n * context), instead of dispatching through a `routingSpec`. Render\n * `<Routes>`/`<Route>` here for fully dynamic routing — no catch-all rule\n * boilerplate. Takes precedence over `routingSpec` for what is rendered.\n */\n children?: ReactNode;\n};\n\nconst updateAlreadyApplied = (filesMetadata: FilesMetadata, update: FilesMetadata) => {\n for (let [key, value] of Object.entries(update)) {\n if (filesMetadata[key] !== value) {\n return false;\n }\n }\n return true;\n};\n\n/** The app shell {@link boot} renders: holds navigation state, subscribes to host\n * URL + metadata pushes, and renders `children` or the route `<Router />`. */\nexport const TinkerableApp = ({ routingSpec, children }: { routingSpec: RoutingSpec; children?: ReactNode }) => {\n const [context, setContext] = useState<TinkerableState>(getInitialContext(routingSpec));\n useEffect(() => {\n const removeListener = addListener(URLCHANGE, ({ url }) => {\n setContext((context) => {\n const updatedContext = updateContext(context, url);\n if (updatedContext !== context) {\n console.log(\n `[Sandbox] Updating path from ${context.navigationState.sandboxPath} to ${updatedContext.navigationState.sandboxPath}`,\n );\n }\n return updatedContext;\n });\n });\n return removeListener;\n }, [setContext]);\n useEffect(() => {\n // Phase 5 dual-mode (SDK_PACKAGING_SPEC §4/§8): prefer the injected bundler's\n // metadata emitter (the live path, byte-identical); when the SDK is npm-fetched\n // with no injection, `event` is undefined so `addListener` receives\n // 'metadata-update' over the §4 transport instead, and `enable` is a no-op.\n const source = resolveMetadataSource(getInjectedMetadataEmitter());\n const dispose = addListener(\n METADATA_UPDATE,\n ({ update }: Record<string, any>) => {\n setContext((prevContext) =>\n updateAlreadyApplied(prevContext.filesMetadata, update)\n ? prevContext\n : {\n ...prevContext,\n filesMetadata: {\n // TODO: file deletion!\n ...prevContext.filesMetadata,\n ...update,\n },\n },\n );\n },\n source.event,\n );\n source.enable();\n return dispose;\n }, [setContext]);\n\n return (\n <TinkerableContext value={context}>\n {/* Capability C: lands cross-page `#fragment` deep-links on their section\n after the destination tree mounts, uniform for every MDX app (§13.5). */}\n <ScrollAfterNavigation />\n {children ?? <Router />}\n </TinkerableContext>\n );\n};\n\n// Boot marker emitter (LOAD_PROFILING_SPEC §3, R3-46). Rendered at the top of the\n// app tree so its layout effect fires on the FIRST root-render commit: that instant\n// is `ir.fmp` (the content is in the DOM, about to paint) and the baseline for\n// `ir.interactive` (the host treats a forwarded `ir.interactive` as the root-commit\n// signal and resolves `max(commit, reportReady)` — LP2-3 — so this can only ever be\n// delayed by an app's `reportReady()`, never advanced). Emitted in canonical stream\n// order (fmp then interactive); idempotent per name (StrictMode-safe). Renders null.\nconst BootMarkers = (): null => {\n useLayoutEffect(() => {\n emitMarkerOnce('ir.fmp');\n emitMarkerOnce('ir.interactive');\n }, []);\n return null;\n};\n\n/** The default route table when `boot` is called with no `routingSpec`/`children`:\n * `/` → main content, `/files/<path>` → the file router, else not-found.\n * Re-expressed with path templates (SANDBOX_ROUTING_SPEC §7); the file path\n * surfaces under the `*` wildcard. The catch-all stays a raw RegExp — the\n * escape hatch — so it anchors `.+` (a non-empty path) exactly as before. */\nexport const DEFAULT_ROUTING_SPEC: RoutingSpec = {\n routes: [\n { name: 'MainContent', pattern: '/', element: <MainContent /> },\n { name: 'FileRouter', pattern: `${FILES_PREFIX}/*`, element: <FileRouter /> },\n { name: 'ErrorNotFound', pattern: /^(?<path>.+)$/, element: <ErrorNotFound /> },\n ],\n};\n\n/**\n * Matches any `sandboxPath` so navigation context can be built without a route\n * table. Used when {@link boot} is given `children` (the app owns dispatch via\n * `<Routes>`); the catch-all's `element` is never rendered (children are).\n */\nexport const CATCH_ALL_ROUTING_SPEC: RoutingSpec = {\n routes: [{ name: 'AppRoot', pattern: /^.*$/, element: null }],\n};\n\n/**\n * Mount an immediately.run app into the sandbox `#root`. The entry point every\n * app calls from `index.tsx`: wires the MDX, module-cache, and navigation\n * providers, then renders the route table (`routingSpec`) or your `children`.\n */\nexport const boot = ({ mdxComponents, routingSpec, children }: BootProps = {}) => {\n const rootElement = document.getElementById('root');\n if (!rootElement) {\n throw new Error('boot requires root HTML element to exist');\n }\n const resolvedComponents = resolveMdxComponents(mdxComponents);\n // `children` own dispatch, so a catch-all keeps navigation working without a\n // table; otherwise fall back to the default file/main-content routes.\n const spec = routingSpec ?? (children ? CATCH_ALL_ROUTING_SPEC : DEFAULT_ROUTING_SPEC);\n const moduleCache = new ModuleCache();\n const root = createRoot(rootElement);\n root.render(\n <StrictMode>\n <ModuleCacheContextProvider moduleCache={moduleCache}>\n <MDXProvider components={resolvedComponents}>\n <BootMarkers />\n <TinkerableApp routingSpec={spec}>{children}</TinkerableApp>\n </MDXProvider>\n </ModuleCacheContextProvider>\n </StrictMode>,\n );\n};\n"],"mappings":"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","names":["context"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/catalog.ts"],"sourcesContent":["// The method catalog (UI_AS_APPS_SPEC §5.5) — the app's own grant-filtered RPC\n// surface, and a generic way to call it. The host advertises exactly the methods\n// this app may invoke (MCP-tool-shaped); `invoke()` calls one by its catalog name.\n// Handing the catalog to an embedded agent as its tool list confines the agent to\n// the app's authority (agent sandboxing falls out of the capability model, §5.9).\nimport { protocolRequest, sendMessage, addListener } from './sandboxUtils';\nimport type { StreamFrame, StreamTransport } from './protocolStream';\nimport { consumeStream } from './protocolStream';\nimport { createPushChannel } from './pushChannel';\nimport { API_CATALOG, REQUEST_API_CATALOG } from './generated/protocol';\n\n/** One advertised method, as the host generated it from its gate table. */\nexport interface ApiMethod {\n /** Catalog name, `protocol-` stripped — e.g. `spaces:invite`, `contribute:run`. */\n name: string;\n /** The capability this method requires (already held — it's in your catalog). */\n capability: string;\n /** True when the method STREAMS (use {@link invokeStream}) vs. single-reply. */\n stream?: boolean;\n /**\n * JSON Schema for the method's single object argument, when the host declares one.\n * Self-describes the call so a catalog-as-tools bridge (an embedded agent) can\n * advertise the real param shape — e.g. that `authoring:typecheck` takes a nested\n * `{ files: [{ path, content }] }` array — instead of a permissive \"any object\".\n * Absent for methods the host advertises without a schema.\n */\n paramsSchema?: Record<string, unknown>;\n}\n\n// `scheme:method` → ['scheme', 'method'] (the wire protocol is `protocol-scheme`).\nconst split = (name: string): [string, string] => {\n const i = name.indexOf(':');\n if (i <= 0) throw new Error(`invalid catalog method name: ${name}`);\n return [name.slice(0, i), name.slice(i + 1)];\n};\n\n/**\n * Call a catalog method by name — `invoke('spaces:invite', { spaceId, login, role })`.\n * A thin generic over the host protocol: the host validates params and gates the\n * call (an un-granted method → `forbidden`, even if you name it directly). For a\n * STREAMING method (`ApiMethod.stream`), use {@link invokeStream}.\n */\nexport const invoke = async <T = unknown>(\n name: string,\n params: Record<string, unknown> = {},\n): Promise<T> => {\n const [scheme, method] = split(name);\n // The host replies with an `{ ok, data } | { ok:false, code }` envelope; unwrap\n // it and THROW on refusal (a `.code` like `forbidden` for an off-catalog call)\n // so callers — and any agent driving `invoke` — see the gate's verdict.\n const res = (await protocolRequest(scheme, method, [params])) as\n | { ok: true; data: unknown }\n | { ok: false; code?: string; message?: string }\n | undefined;\n if (!res || res.ok !== true) {\n const err = new Error(res?.message ?? `${name} failed`) as Error & { code?: string };\n err.code = res?.code ?? 'unknown';\n throw err;\n }\n return res.data as T;\n};\n\n// Stream transport over the resolver (SDK_PACKAGING_SPEC §4) — sendMessage /\n// addListener route through `transport()` (injected bundler messageBus or the §4\n// global), never `bundler.messageBus` directly.\nconst streamTransport: StreamTransport = {\n send: (msg) => sendMessage(msg.type, msg as unknown as Record<string, unknown>),\n subscribe: (type, handler) =>\n addListener(type, (msg) => handler(msg as { msgId?: number; stream?: StreamFrame })),\n // Early-cancel: route a `{type, msgId, cancel:true}` frame back to the host so it\n // aborts the in-flight generation (and, for `llm:chat`, stops billing) — §3.3.\n cancel: (msg) => sendMessage(msg.type, msg as unknown as Record<string, unknown>),\n};\n\n/** Call a STREAMING catalog method by name, yielding its events. Pass `signal` to\n * abort mid-stream: the host stops generating and (for `llm:chat`) stops billing. */\nexport function invokeStream<T = unknown, R = unknown>(\n name: string,\n params: Record<string, unknown> = {},\n signal?: AbortSignal,\n): AsyncGenerator<T, R, void> {\n const [scheme, method] = split(name);\n return consumeStream<T, R>(streamTransport, `protocol-${scheme}`, method, [params], undefined, signal);\n}\n\n// The catalog list is read over the transport (§4): the host pushes `api-catalog`\n// and answers `request-api-catalog` with this app's grant-filtered methods (wire\n// format: site-main channelBridge.ts).\nconst channel = createPushChannel<ApiMethod[]>({\n pushType: API_CATALOG,\n requestType: REQUEST_API_CATALOG,\n initial: [],\n parse: (msg) => (Array.isArray(msg.methods) ? (msg.methods as ApiMethod[]) : undefined),\n});\n\n/** The methods this app may call (grant-filtered, §5.5). Poll for a one-off read;\n * use {@link onCatalogChange} / {@link useCatalog} to react. */\nexport const getCatalog = (): ApiMethod[] => channel.get();\n\n/** Subscribe to catalog changes (e.g. a grant added/revoked). Invoked immediately\n * with the current catalog, then on every change. Returns an unsubscribe fn. */\nexport const onCatalogChange = (listener: (catalog: ApiMethod[]) => void): (() => void) =>\n channel.onChange(listener);\n\n/** React hook returning this app's method catalog, re-rendering on change. Hand\n * it to an embedded agent as its tool list to confine the agent to the app's\n * authority (§5.9). */\nexport const useCatalog = (): ApiMethod[] => channel.use();\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA,0BAA0D;AAE1D,4BAA8B;AAC9B,yBAAkC;AAClC,sBAAiD;AAqBjD,MAAM,QAAQ,CAAC,SAAmC;AAChD,QAAM,IAAI,KAAK,QAAQ,GAAG;AAC1B,MAAI,KAAK,EAAG,OAAM,IAAI,MAAM,gCAAgC,IAAI,EAAE;AAClE,SAAO,CAAC,KAAK,MAAM,GAAG,CAAC,GAAG,KAAK,MAAM,IAAI,CAAC,CAAC;AAC7C;AAQO,MAAM,SAAS,OACpB,MACA,SAAkC,CAAC,MACpB;AACf,QAAM,CAAC,QAAQ,MAAM,IAAI,MAAM,IAAI;AAInC,QAAM,MAAO,UAAM,qCAAgB,QAAQ,QAAQ,CAAC,MAAM,CAAC;AAI3D,MAAI,CAAC,OAAO,IAAI,OAAO,MAAM;AAC3B,UAAM,MAAM,IAAI,MAAM,KAAK,WAAW,GAAG,IAAI,SAAS;AACtD,QAAI,OAAO,KAAK,QAAQ;AACxB,UAAM;AAAA,EACR;AACA,SAAO,IAAI;AACb;AAKA,MAAM,kBAAmC;AAAA,EACvC,MAAM,CAAC,YAAQ,iCAAY,IAAI,MAAM,GAAyC;AAAA,EAC9E,WAAW,CAAC,MAAM,gBAChB,iCAAY,MAAM,CAAC,QAAQ,QAAQ,GAA+C,CAAC;AAAA;AAAA;AAAA,EAGrF,QAAQ,CAAC,YAAQ,iCAAY,IAAI,MAAM,GAAyC;AAClF;AAIO,SAAS,aACd,MACA,SAAkC,CAAC,GACnC,QAC4B;AAC5B,QAAM,CAAC,QAAQ,MAAM,IAAI,MAAM,IAAI;AACnC,aAAO,qCAAoB,iBAAiB,YAAY,MAAM,IAAI,QAAQ,CAAC,MAAM,GAAG,QAAW,MAAM;AACvG;AAKA,MAAM,cAAU,sCAA+B;AAAA,EAC7C,UAAU;AAAA,EACV,aAAa;AAAA,EACb,SAAS,CAAC;AAAA,EACV,OAAO,CAAC,QAAS,MAAM,QAAQ,IAAI,OAAO,IAAK,IAAI,UAA0B;AAC/E,CAAC;AAIM,MAAM,aAAa,MAAmB,QAAQ,IAAI;AAIlD,MAAM,kBAAkB,CAAC,aAC9B,QAAQ,SAAS,QAAQ;AAKpB,MAAM,aAAa,MAAmB,QAAQ,IAAI;","names":[]}
1
+ {"version":3,"sources":["../src/catalog.ts"],"sourcesContent":["// The method catalog (UI_AS_APPS_SPEC §5.5) — the app's own grant-filtered RPC\n// surface, and a generic way to call it. The host advertises exactly the methods\n// this app may invoke (MCP-tool-shaped); `invoke()` calls one by its catalog name.\n// Handing the catalog to an embedded agent as its tool list confines the agent to\n// the app's authority (agent sandboxing falls out of the capability model, §5.9).\nimport { protocolRequest, sendMessage, addListener } from './sandboxUtils';\nimport type { StreamFrame, StreamTransport } from './protocolStream';\nimport { consumeStream } from './protocolStream';\nimport { createPushChannel } from './pushChannel';\nimport { API_CATALOG, REQUEST_API_CATALOG } from './generated/protocol';\n\n/** One advertised method, as the host generated it from its gate table. */\nexport interface ApiMethod {\n /** Catalog name, `protocol-` stripped — e.g. `spaces:invite`, `contribute:run`. */\n name: string;\n /** The capability this method requires (already held — it's in your catalog). */\n capability: string;\n /** True when the method STREAMS (use {@link invokeStream}) vs. single-reply. */\n stream?: boolean;\n /**\n * JSON Schema for the method's single object argument, when the host declares one.\n * Self-describes the call so a catalog-as-tools bridge (an embedded agent) can\n * advertise the real param shape — e.g. that `authoring:typecheck` takes a nested\n * `{ files: [{ path, content }] }` array — instead of a permissive \"any object\".\n * Absent for methods the host advertises without a schema.\n */\n paramsSchema?: Record<string, unknown>;\n}\n\n// `scheme:method` → ['scheme', 'method'] (the wire protocol is `protocol-scheme`).\nconst split = (name: string): [string, string] => {\n const i = name.indexOf(':');\n if (i <= 0) throw new Error(`invalid catalog method name: ${name}`);\n return [name.slice(0, i), name.slice(i + 1)];\n};\n\n/**\n * Call a catalog method by name — `invoke('spaces:invite', { spaceId, login, role })`.\n * A thin generic over the host protocol: the host validates params and gates the\n * call (an un-granted method → `forbidden`, even if you name it directly). For a\n * STREAMING method (`ApiMethod.stream`), use {@link invokeStream}.\n */\nexport const invoke = async <T = unknown>(name: string, params: Record<string, unknown> = {}): Promise<T> => {\n const [scheme, method] = split(name);\n // The host replies with an `{ ok, data } | { ok:false, code }` envelope; unwrap\n // it and THROW on refusal (a `.code` like `forbidden` for an off-catalog call)\n // so callers — and any agent driving `invoke` — see the gate's verdict.\n const res = (await protocolRequest(scheme, method, [params])) as\n | { ok: true; data: unknown }\n | { ok: false; code?: string; message?: string }\n | undefined;\n if (!res || res.ok !== true) {\n const err = new Error(res?.message ?? `${name} failed`) as Error & { code?: string };\n err.code = res?.code ?? 'unknown';\n throw err;\n }\n return res.data as T;\n};\n\n// Stream transport over the resolver (SDK_PACKAGING_SPEC §4) — sendMessage /\n// addListener route through `transport()` (injected bundler messageBus or the §4\n// global), never `bundler.messageBus` directly.\nconst streamTransport: StreamTransport = {\n send: (msg) => sendMessage(msg.type, msg as unknown as Record<string, unknown>),\n subscribe: (type, handler) => addListener(type, (msg) => handler(msg as { msgId?: number; stream?: StreamFrame })),\n // Early-cancel: route a `{type, msgId, cancel:true}` frame back to the host so it\n // aborts the in-flight generation (and, for `llm:chat`, stops billing) — §3.3.\n cancel: (msg) => sendMessage(msg.type, msg as unknown as Record<string, unknown>),\n};\n\n/** Call a STREAMING catalog method by name, yielding its events. Pass `signal` to\n * abort mid-stream: the host stops generating and (for `llm:chat`) stops billing. */\nexport function invokeStream<T = unknown, R = unknown>(\n name: string,\n params: Record<string, unknown> = {},\n signal?: AbortSignal,\n): AsyncGenerator<T, R, void> {\n const [scheme, method] = split(name);\n return consumeStream<T, R>(streamTransport, `protocol-${scheme}`, method, [params], undefined, signal);\n}\n\n// The catalog list is read over the transport (§4): the host pushes `api-catalog`\n// and answers `request-api-catalog` with this app's grant-filtered methods (wire\n// format: site-main channelBridge.ts).\nconst channel = createPushChannel<ApiMethod[]>({\n pushType: API_CATALOG,\n requestType: REQUEST_API_CATALOG,\n initial: [],\n parse: (msg) => (Array.isArray(msg.methods) ? (msg.methods as ApiMethod[]) : undefined),\n});\n\n/** The methods this app may call (grant-filtered, §5.5). Poll for a one-off read;\n * use {@link onCatalogChange} / {@link useCatalog} to react. */\nexport const getCatalog = (): ApiMethod[] => channel.get();\n\n/** Subscribe to catalog changes (e.g. a grant added/revoked). Invoked immediately\n * with the current catalog, then on every change. Returns an unsubscribe fn. */\nexport const onCatalogChange = (listener: (catalog: ApiMethod[]) => void): (() => void) => channel.onChange(listener);\n\n/** React hook returning this app's method catalog, re-rendering on change. Hand\n * it to an embedded agent as its tool list to confine the agent to the app's\n * authority (§5.9). */\nexport const useCatalog = (): ApiMethod[] => channel.use();\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA,0BAA0D;AAE1D,4BAA8B;AAC9B,yBAAkC;AAClC,sBAAiD;AAqBjD,MAAM,QAAQ,CAAC,SAAmC;AAChD,QAAM,IAAI,KAAK,QAAQ,GAAG;AAC1B,MAAI,KAAK,EAAG,OAAM,IAAI,MAAM,gCAAgC,IAAI,EAAE;AAClE,SAAO,CAAC,KAAK,MAAM,GAAG,CAAC,GAAG,KAAK,MAAM,IAAI,CAAC,CAAC;AAC7C;AAQO,MAAM,SAAS,OAAoB,MAAc,SAAkC,CAAC,MAAkB;AAC3G,QAAM,CAAC,QAAQ,MAAM,IAAI,MAAM,IAAI;AAInC,QAAM,MAAO,UAAM,qCAAgB,QAAQ,QAAQ,CAAC,MAAM,CAAC;AAI3D,MAAI,CAAC,OAAO,IAAI,OAAO,MAAM;AAC3B,UAAM,MAAM,IAAI,MAAM,KAAK,WAAW,GAAG,IAAI,SAAS;AACtD,QAAI,OAAO,KAAK,QAAQ;AACxB,UAAM;AAAA,EACR;AACA,SAAO,IAAI;AACb;AAKA,MAAM,kBAAmC;AAAA,EACvC,MAAM,CAAC,YAAQ,iCAAY,IAAI,MAAM,GAAyC;AAAA,EAC9E,WAAW,CAAC,MAAM,gBAAY,iCAAY,MAAM,CAAC,QAAQ,QAAQ,GAA+C,CAAC;AAAA;AAAA;AAAA,EAGjH,QAAQ,CAAC,YAAQ,iCAAY,IAAI,MAAM,GAAyC;AAClF;AAIO,SAAS,aACd,MACA,SAAkC,CAAC,GACnC,QAC4B;AAC5B,QAAM,CAAC,QAAQ,MAAM,IAAI,MAAM,IAAI;AACnC,aAAO,qCAAoB,iBAAiB,YAAY,MAAM,IAAI,QAAQ,CAAC,MAAM,GAAG,QAAW,MAAM;AACvG;AAKA,MAAM,cAAU,sCAA+B;AAAA,EAC7C,UAAU;AAAA,EACV,aAAa;AAAA,EACb,SAAS,CAAC;AAAA,EACV,OAAO,CAAC,QAAS,MAAM,QAAQ,IAAI,OAAO,IAAK,IAAI,UAA0B;AAC/E,CAAC;AAIM,MAAM,aAAa,MAAmB,QAAQ,IAAI;AAIlD,MAAM,kBAAkB,CAAC,aAA2D,QAAQ,SAAS,QAAQ;AAK7G,MAAM,aAAa,MAAmB,QAAQ,IAAI;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/catalog.ts"],"sourcesContent":["// The method catalog (UI_AS_APPS_SPEC §5.5) — the app's own grant-filtered RPC\n// surface, and a generic way to call it. The host advertises exactly the methods\n// this app may invoke (MCP-tool-shaped); `invoke()` calls one by its catalog name.\n// Handing the catalog to an embedded agent as its tool list confines the agent to\n// the app's authority (agent sandboxing falls out of the capability model, §5.9).\nimport { protocolRequest, sendMessage, addListener } from './sandboxUtils';\nimport type { StreamFrame, StreamTransport } from './protocolStream';\nimport { consumeStream } from './protocolStream';\nimport { createPushChannel } from './pushChannel';\nimport { API_CATALOG, REQUEST_API_CATALOG } from './generated/protocol';\n\n/** One advertised method, as the host generated it from its gate table. */\nexport interface ApiMethod {\n /** Catalog name, `protocol-` stripped — e.g. `spaces:invite`, `contribute:run`. */\n name: string;\n /** The capability this method requires (already held — it's in your catalog). */\n capability: string;\n /** True when the method STREAMS (use {@link invokeStream}) vs. single-reply. */\n stream?: boolean;\n /**\n * JSON Schema for the method's single object argument, when the host declares one.\n * Self-describes the call so a catalog-as-tools bridge (an embedded agent) can\n * advertise the real param shape — e.g. that `authoring:typecheck` takes a nested\n * `{ files: [{ path, content }] }` array — instead of a permissive \"any object\".\n * Absent for methods the host advertises without a schema.\n */\n paramsSchema?: Record<string, unknown>;\n}\n\n// `scheme:method` → ['scheme', 'method'] (the wire protocol is `protocol-scheme`).\nconst split = (name: string): [string, string] => {\n const i = name.indexOf(':');\n if (i <= 0) throw new Error(`invalid catalog method name: ${name}`);\n return [name.slice(0, i), name.slice(i + 1)];\n};\n\n/**\n * Call a catalog method by name — `invoke('spaces:invite', { spaceId, login, role })`.\n * A thin generic over the host protocol: the host validates params and gates the\n * call (an un-granted method → `forbidden`, even if you name it directly). For a\n * STREAMING method (`ApiMethod.stream`), use {@link invokeStream}.\n */\nexport const invoke = async <T = unknown>(\n name: string,\n params: Record<string, unknown> = {},\n): Promise<T> => {\n const [scheme, method] = split(name);\n // The host replies with an `{ ok, data } | { ok:false, code }` envelope; unwrap\n // it and THROW on refusal (a `.code` like `forbidden` for an off-catalog call)\n // so callers — and any agent driving `invoke` — see the gate's verdict.\n const res = (await protocolRequest(scheme, method, [params])) as\n | { ok: true; data: unknown }\n | { ok: false; code?: string; message?: string }\n | undefined;\n if (!res || res.ok !== true) {\n const err = new Error(res?.message ?? `${name} failed`) as Error & { code?: string };\n err.code = res?.code ?? 'unknown';\n throw err;\n }\n return res.data as T;\n};\n\n// Stream transport over the resolver (SDK_PACKAGING_SPEC §4) — sendMessage /\n// addListener route through `transport()` (injected bundler messageBus or the §4\n// global), never `bundler.messageBus` directly.\nconst streamTransport: StreamTransport = {\n send: (msg) => sendMessage(msg.type, msg as unknown as Record<string, unknown>),\n subscribe: (type, handler) =>\n addListener(type, (msg) => handler(msg as { msgId?: number; stream?: StreamFrame })),\n // Early-cancel: route a `{type, msgId, cancel:true}` frame back to the host so it\n // aborts the in-flight generation (and, for `llm:chat`, stops billing) — §3.3.\n cancel: (msg) => sendMessage(msg.type, msg as unknown as Record<string, unknown>),\n};\n\n/** Call a STREAMING catalog method by name, yielding its events. Pass `signal` to\n * abort mid-stream: the host stops generating and (for `llm:chat`) stops billing. */\nexport function invokeStream<T = unknown, R = unknown>(\n name: string,\n params: Record<string, unknown> = {},\n signal?: AbortSignal,\n): AsyncGenerator<T, R, void> {\n const [scheme, method] = split(name);\n return consumeStream<T, R>(streamTransport, `protocol-${scheme}`, method, [params], undefined, signal);\n}\n\n// The catalog list is read over the transport (§4): the host pushes `api-catalog`\n// and answers `request-api-catalog` with this app's grant-filtered methods (wire\n// format: site-main channelBridge.ts).\nconst channel = createPushChannel<ApiMethod[]>({\n pushType: API_CATALOG,\n requestType: REQUEST_API_CATALOG,\n initial: [],\n parse: (msg) => (Array.isArray(msg.methods) ? (msg.methods as ApiMethod[]) : undefined),\n});\n\n/** The methods this app may call (grant-filtered, §5.5). Poll for a one-off read;\n * use {@link onCatalogChange} / {@link useCatalog} to react. */\nexport const getCatalog = (): ApiMethod[] => channel.get();\n\n/** Subscribe to catalog changes (e.g. a grant added/revoked). Invoked immediately\n * with the current catalog, then on every change. Returns an unsubscribe fn. */\nexport const onCatalogChange = (listener: (catalog: ApiMethod[]) => void): (() => void) =>\n channel.onChange(listener);\n\n/** React hook returning this app's method catalog, re-rendering on change. Hand\n * it to an embedded agent as its tool list to confine the agent to the app's\n * authority (§5.9). */\nexport const useCatalog = (): ApiMethod[] => channel.use();\n"],"mappings":";AAKA,SAAS,iBAAiB,aAAa,mBAAmB;AAE1D,SAAS,qBAAqB;AAC9B,SAAS,yBAAyB;AAClC,SAAS,aAAa,2BAA2B;AAqBjD,MAAM,QAAQ,CAAC,SAAmC;AAChD,QAAM,IAAI,KAAK,QAAQ,GAAG;AAC1B,MAAI,KAAK,EAAG,OAAM,IAAI,MAAM,gCAAgC,IAAI,EAAE;AAClE,SAAO,CAAC,KAAK,MAAM,GAAG,CAAC,GAAG,KAAK,MAAM,IAAI,CAAC,CAAC;AAC7C;AAQO,MAAM,SAAS,OACpB,MACA,SAAkC,CAAC,MACpB;AACf,QAAM,CAAC,QAAQ,MAAM,IAAI,MAAM,IAAI;AAInC,QAAM,MAAO,MAAM,gBAAgB,QAAQ,QAAQ,CAAC,MAAM,CAAC;AAI3D,MAAI,CAAC,OAAO,IAAI,OAAO,MAAM;AAC3B,UAAM,MAAM,IAAI,MAAM,KAAK,WAAW,GAAG,IAAI,SAAS;AACtD,QAAI,OAAO,KAAK,QAAQ;AACxB,UAAM;AAAA,EACR;AACA,SAAO,IAAI;AACb;AAKA,MAAM,kBAAmC;AAAA,EACvC,MAAM,CAAC,QAAQ,YAAY,IAAI,MAAM,GAAyC;AAAA,EAC9E,WAAW,CAAC,MAAM,YAChB,YAAY,MAAM,CAAC,QAAQ,QAAQ,GAA+C,CAAC;AAAA;AAAA;AAAA,EAGrF,QAAQ,CAAC,QAAQ,YAAY,IAAI,MAAM,GAAyC;AAClF;AAIO,SAAS,aACd,MACA,SAAkC,CAAC,GACnC,QAC4B;AAC5B,QAAM,CAAC,QAAQ,MAAM,IAAI,MAAM,IAAI;AACnC,SAAO,cAAoB,iBAAiB,YAAY,MAAM,IAAI,QAAQ,CAAC,MAAM,GAAG,QAAW,MAAM;AACvG;AAKA,MAAM,UAAU,kBAA+B;AAAA,EAC7C,UAAU;AAAA,EACV,aAAa;AAAA,EACb,SAAS,CAAC;AAAA,EACV,OAAO,CAAC,QAAS,MAAM,QAAQ,IAAI,OAAO,IAAK,IAAI,UAA0B;AAC/E,CAAC;AAIM,MAAM,aAAa,MAAmB,QAAQ,IAAI;AAIlD,MAAM,kBAAkB,CAAC,aAC9B,QAAQ,SAAS,QAAQ;AAKpB,MAAM,aAAa,MAAmB,QAAQ,IAAI;","names":[]}
1
+ {"version":3,"sources":["../src/catalog.ts"],"sourcesContent":["// The method catalog (UI_AS_APPS_SPEC §5.5) — the app's own grant-filtered RPC\n// surface, and a generic way to call it. The host advertises exactly the methods\n// this app may invoke (MCP-tool-shaped); `invoke()` calls one by its catalog name.\n// Handing the catalog to an embedded agent as its tool list confines the agent to\n// the app's authority (agent sandboxing falls out of the capability model, §5.9).\nimport { protocolRequest, sendMessage, addListener } from './sandboxUtils';\nimport type { StreamFrame, StreamTransport } from './protocolStream';\nimport { consumeStream } from './protocolStream';\nimport { createPushChannel } from './pushChannel';\nimport { API_CATALOG, REQUEST_API_CATALOG } from './generated/protocol';\n\n/** One advertised method, as the host generated it from its gate table. */\nexport interface ApiMethod {\n /** Catalog name, `protocol-` stripped — e.g. `spaces:invite`, `contribute:run`. */\n name: string;\n /** The capability this method requires (already held — it's in your catalog). */\n capability: string;\n /** True when the method STREAMS (use {@link invokeStream}) vs. single-reply. */\n stream?: boolean;\n /**\n * JSON Schema for the method's single object argument, when the host declares one.\n * Self-describes the call so a catalog-as-tools bridge (an embedded agent) can\n * advertise the real param shape — e.g. that `authoring:typecheck` takes a nested\n * `{ files: [{ path, content }] }` array — instead of a permissive \"any object\".\n * Absent for methods the host advertises without a schema.\n */\n paramsSchema?: Record<string, unknown>;\n}\n\n// `scheme:method` → ['scheme', 'method'] (the wire protocol is `protocol-scheme`).\nconst split = (name: string): [string, string] => {\n const i = name.indexOf(':');\n if (i <= 0) throw new Error(`invalid catalog method name: ${name}`);\n return [name.slice(0, i), name.slice(i + 1)];\n};\n\n/**\n * Call a catalog method by name — `invoke('spaces:invite', { spaceId, login, role })`.\n * A thin generic over the host protocol: the host validates params and gates the\n * call (an un-granted method → `forbidden`, even if you name it directly). For a\n * STREAMING method (`ApiMethod.stream`), use {@link invokeStream}.\n */\nexport const invoke = async <T = unknown>(name: string, params: Record<string, unknown> = {}): Promise<T> => {\n const [scheme, method] = split(name);\n // The host replies with an `{ ok, data } | { ok:false, code }` envelope; unwrap\n // it and THROW on refusal (a `.code` like `forbidden` for an off-catalog call)\n // so callers — and any agent driving `invoke` — see the gate's verdict.\n const res = (await protocolRequest(scheme, method, [params])) as\n | { ok: true; data: unknown }\n | { ok: false; code?: string; message?: string }\n | undefined;\n if (!res || res.ok !== true) {\n const err = new Error(res?.message ?? `${name} failed`) as Error & { code?: string };\n err.code = res?.code ?? 'unknown';\n throw err;\n }\n return res.data as T;\n};\n\n// Stream transport over the resolver (SDK_PACKAGING_SPEC §4) — sendMessage /\n// addListener route through `transport()` (injected bundler messageBus or the §4\n// global), never `bundler.messageBus` directly.\nconst streamTransport: StreamTransport = {\n send: (msg) => sendMessage(msg.type, msg as unknown as Record<string, unknown>),\n subscribe: (type, handler) => addListener(type, (msg) => handler(msg as { msgId?: number; stream?: StreamFrame })),\n // Early-cancel: route a `{type, msgId, cancel:true}` frame back to the host so it\n // aborts the in-flight generation (and, for `llm:chat`, stops billing) — §3.3.\n cancel: (msg) => sendMessage(msg.type, msg as unknown as Record<string, unknown>),\n};\n\n/** Call a STREAMING catalog method by name, yielding its events. Pass `signal` to\n * abort mid-stream: the host stops generating and (for `llm:chat`) stops billing. */\nexport function invokeStream<T = unknown, R = unknown>(\n name: string,\n params: Record<string, unknown> = {},\n signal?: AbortSignal,\n): AsyncGenerator<T, R, void> {\n const [scheme, method] = split(name);\n return consumeStream<T, R>(streamTransport, `protocol-${scheme}`, method, [params], undefined, signal);\n}\n\n// The catalog list is read over the transport (§4): the host pushes `api-catalog`\n// and answers `request-api-catalog` with this app's grant-filtered methods (wire\n// format: site-main channelBridge.ts).\nconst channel = createPushChannel<ApiMethod[]>({\n pushType: API_CATALOG,\n requestType: REQUEST_API_CATALOG,\n initial: [],\n parse: (msg) => (Array.isArray(msg.methods) ? (msg.methods as ApiMethod[]) : undefined),\n});\n\n/** The methods this app may call (grant-filtered, §5.5). Poll for a one-off read;\n * use {@link onCatalogChange} / {@link useCatalog} to react. */\nexport const getCatalog = (): ApiMethod[] => channel.get();\n\n/** Subscribe to catalog changes (e.g. a grant added/revoked). Invoked immediately\n * with the current catalog, then on every change. Returns an unsubscribe fn. */\nexport const onCatalogChange = (listener: (catalog: ApiMethod[]) => void): (() => void) => channel.onChange(listener);\n\n/** React hook returning this app's method catalog, re-rendering on change. Hand\n * it to an embedded agent as its tool list to confine the agent to the app's\n * authority (§5.9). */\nexport const useCatalog = (): ApiMethod[] => channel.use();\n"],"mappings":";AAKA,SAAS,iBAAiB,aAAa,mBAAmB;AAE1D,SAAS,qBAAqB;AAC9B,SAAS,yBAAyB;AAClC,SAAS,aAAa,2BAA2B;AAqBjD,MAAM,QAAQ,CAAC,SAAmC;AAChD,QAAM,IAAI,KAAK,QAAQ,GAAG;AAC1B,MAAI,KAAK,EAAG,OAAM,IAAI,MAAM,gCAAgC,IAAI,EAAE;AAClE,SAAO,CAAC,KAAK,MAAM,GAAG,CAAC,GAAG,KAAK,MAAM,IAAI,CAAC,CAAC;AAC7C;AAQO,MAAM,SAAS,OAAoB,MAAc,SAAkC,CAAC,MAAkB;AAC3G,QAAM,CAAC,QAAQ,MAAM,IAAI,MAAM,IAAI;AAInC,QAAM,MAAO,MAAM,gBAAgB,QAAQ,QAAQ,CAAC,MAAM,CAAC;AAI3D,MAAI,CAAC,OAAO,IAAI,OAAO,MAAM;AAC3B,UAAM,MAAM,IAAI,MAAM,KAAK,WAAW,GAAG,IAAI,SAAS;AACtD,QAAI,OAAO,KAAK,QAAQ;AACxB,UAAM;AAAA,EACR;AACA,SAAO,IAAI;AACb;AAKA,MAAM,kBAAmC;AAAA,EACvC,MAAM,CAAC,QAAQ,YAAY,IAAI,MAAM,GAAyC;AAAA,EAC9E,WAAW,CAAC,MAAM,YAAY,YAAY,MAAM,CAAC,QAAQ,QAAQ,GAA+C,CAAC;AAAA;AAAA;AAAA,EAGjH,QAAQ,CAAC,QAAQ,YAAY,IAAI,MAAM,GAAyC;AAClF;AAIO,SAAS,aACd,MACA,SAAkC,CAAC,GACnC,QAC4B;AAC5B,QAAM,CAAC,QAAQ,MAAM,IAAI,MAAM,IAAI;AACnC,SAAO,cAAoB,iBAAiB,YAAY,MAAM,IAAI,QAAQ,CAAC,MAAM,GAAG,QAAW,MAAM;AACvG;AAKA,MAAM,UAAU,kBAA+B;AAAA,EAC7C,UAAU;AAAA,EACV,aAAa;AAAA,EACb,SAAS,CAAC;AAAA,EACV,OAAO,CAAC,QAAS,MAAM,QAAQ,IAAI,OAAO,IAAK,IAAI,UAA0B;AAC/E,CAAC;AAIM,MAAM,aAAa,MAAmB,QAAQ,IAAI;AAIlD,MAAM,kBAAkB,CAAC,aAA2D,QAAQ,SAAS,QAAQ;AAK7G,MAAM,aAAa,MAAmB,QAAQ,IAAI;","names":[]}
@@ -37,19 +37,10 @@ const Admonition = ({
37
37
  }) => {
38
38
  const kind = String(type).toLowerCase();
39
39
  const label = title ?? TITLES[kind] ?? TITLES.note;
40
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
41
- "div",
42
- {
43
- className: `ir-admonition ir-admonition-${kind}`,
44
- role: "note",
45
- "data-admonition": kind,
46
- ...rest,
47
- children: [
48
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "ir-admonition-title", children: label }),
49
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "ir-admonition-body", children })
50
- ]
51
- }
52
- );
40
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: `ir-admonition ir-admonition-${kind}`, role: "note", "data-admonition": kind, ...rest, children: [
41
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "ir-admonition-title", children: label }),
42
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "ir-admonition-body", children })
43
+ ] });
53
44
  };
54
45
  // Annotate the CommonJS export names for ESM import in node:
55
46
  0 && (module.exports = {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/Admonition.tsx"],"sourcesContent":["import { ReactNode } from 'react';\n\n/** The GitHub admonition kinds the transpiler's `> [!TYPE]` plugin emits (R3-152). */\nexport type AdmonitionType = 'note' | 'tip' | 'important' | 'warning' | 'caution';\n\nconst TITLES: Record<string, string> = {\n note: 'Note',\n tip: 'Tip',\n important: 'Important',\n warning: 'Warning',\n caution: 'Caution',\n};\n\n/**\n * Default MDX `Admonition` component — the render target for the GitHub-style\n * `> [!NOTE]` blockquote-alert syntax (the transpiler remark plugin, R3-152,\n * compiles that syntax to `<Admonition type=\"note\">…</Admonition>`).\n *\n * It is registered in {@link DEFAULT_MDX_COMPONENTS} so an admonition renders\n * even in a plain-markdown repo that never calls `boot({ mdxComponents })` — the\n * MDX missing-reference guard never fires (MARKDOWN_SYNTAX_SPEC §11.2 phantom\n * defaults). The markup is semantic and accessible; **styling is intentionally\n * minimal** — an app supplies CSS targeting the `ir-admonition*` classes, or\n * overrides this component via `boot({ mdxComponents: { Admonition } })`\n * (MARKDOWN_SYNTAX_SPEC §12.3).\n */\nexport const Admonition = ({\n type = 'note',\n title,\n children,\n ...rest\n}: {\n type?: AdmonitionType | string;\n title?: ReactNode;\n children?: ReactNode;\n} & Omit<React.HTMLAttributes<HTMLDivElement>, 'title'>): ReactNode => {\n const kind = String(type).toLowerCase();\n const label = title ?? TITLES[kind] ?? TITLES.note;\n return (\n <div\n className={`ir-admonition ir-admonition-${kind}`}\n role=\"note\"\n data-admonition={kind}\n {...rest}\n >\n <p className=\"ir-admonition-title\">{label}</p>\n <div className=\"ir-admonition-body\">{children}</div>\n </div>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAuCI;AAlCJ,MAAM,SAAiC;AAAA,EACrC,MAAM;AAAA,EACN,KAAK;AAAA,EACL,WAAW;AAAA,EACX,SAAS;AAAA,EACT,SAAS;AACX;AAeO,MAAM,aAAa,CAAC;AAAA,EACzB,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAIuE;AACrE,QAAM,OAAO,OAAO,IAAI,EAAE,YAAY;AACtC,QAAM,QAAQ,SAAS,OAAO,IAAI,KAAK,OAAO;AAC9C,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,+BAA+B,IAAI;AAAA,MAC9C,MAAK;AAAA,MACL,mBAAiB;AAAA,MAChB,GAAG;AAAA,MAEJ;AAAA,oDAAC,OAAE,WAAU,uBAAuB,iBAAM;AAAA,QAC1C,4CAAC,SAAI,WAAU,sBAAsB,UAAS;AAAA;AAAA;AAAA,EAChD;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/Admonition.tsx"],"sourcesContent":["import { ReactNode } from 'react';\n\n/** The GitHub admonition kinds the transpiler's `> [!TYPE]` plugin emits (R3-152). */\nexport type AdmonitionType = 'note' | 'tip' | 'important' | 'warning' | 'caution';\n\nconst TITLES: Record<string, string> = {\n note: 'Note',\n tip: 'Tip',\n important: 'Important',\n warning: 'Warning',\n caution: 'Caution',\n};\n\n/**\n * Default MDX `Admonition` component — the render target for the GitHub-style\n * `> [!NOTE]` blockquote-alert syntax (the transpiler remark plugin, R3-152,\n * compiles that syntax to `<Admonition type=\"note\">…</Admonition>`).\n *\n * It is registered in {@link DEFAULT_MDX_COMPONENTS} so an admonition renders\n * even in a plain-markdown repo that never calls `boot({ mdxComponents })` — the\n * MDX missing-reference guard never fires (MARKDOWN_SYNTAX_SPEC §11.2 phantom\n * defaults). The markup is semantic and accessible; **styling is intentionally\n * minimal** — an app supplies CSS targeting the `ir-admonition*` classes, or\n * overrides this component via `boot({ mdxComponents: { Admonition } })`\n * (MARKDOWN_SYNTAX_SPEC §12.3).\n */\nexport const Admonition = ({\n type = 'note',\n title,\n children,\n ...rest\n}: {\n type?: AdmonitionType | string;\n title?: ReactNode;\n children?: ReactNode;\n} & Omit<React.HTMLAttributes<HTMLDivElement>, 'title'>): ReactNode => {\n const kind = String(type).toLowerCase();\n const label = title ?? TITLES[kind] ?? TITLES.note;\n return (\n <div className={`ir-admonition ir-admonition-${kind}`} role=\"note\" data-admonition={kind} {...rest}>\n <p className=\"ir-admonition-title\">{label}</p>\n <div className=\"ir-admonition-body\">{children}</div>\n </div>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAuCI;AAlCJ,MAAM,SAAiC;AAAA,EACrC,MAAM;AAAA,EACN,KAAK;AAAA,EACL,WAAW;AAAA,EACX,SAAS;AAAA,EACT,SAAS;AACX;AAeO,MAAM,aAAa,CAAC;AAAA,EACzB,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAIuE;AACrE,QAAM,OAAO,OAAO,IAAI,EAAE,YAAY;AACtC,QAAM,QAAQ,SAAS,OAAO,IAAI,KAAK,OAAO;AAC9C,SACE,6CAAC,SAAI,WAAW,+BAA+B,IAAI,IAAI,MAAK,QAAO,mBAAiB,MAAO,GAAG,MAC5F;AAAA,gDAAC,OAAE,WAAU,uBAAuB,iBAAM;AAAA,IAC1C,4CAAC,SAAI,WAAU,sBAAsB,UAAS;AAAA,KAChD;AAEJ;","names":[]}
@@ -15,19 +15,10 @@ const Admonition = ({
15
15
  }) => {
16
16
  const kind = String(type).toLowerCase();
17
17
  const label = title ?? TITLES[kind] ?? TITLES.note;
18
- return /* @__PURE__ */ jsxs(
19
- "div",
20
- {
21
- className: `ir-admonition ir-admonition-${kind}`,
22
- role: "note",
23
- "data-admonition": kind,
24
- ...rest,
25
- children: [
26
- /* @__PURE__ */ jsx("p", { className: "ir-admonition-title", children: label }),
27
- /* @__PURE__ */ jsx("div", { className: "ir-admonition-body", children })
28
- ]
29
- }
30
- );
18
+ return /* @__PURE__ */ jsxs("div", { className: `ir-admonition ir-admonition-${kind}`, role: "note", "data-admonition": kind, ...rest, children: [
19
+ /* @__PURE__ */ jsx("p", { className: "ir-admonition-title", children: label }),
20
+ /* @__PURE__ */ jsx("div", { className: "ir-admonition-body", children })
21
+ ] });
31
22
  };
32
23
  export {
33
24
  Admonition
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/Admonition.tsx"],"sourcesContent":["import { ReactNode } from 'react';\n\n/** The GitHub admonition kinds the transpiler's `> [!TYPE]` plugin emits (R3-152). */\nexport type AdmonitionType = 'note' | 'tip' | 'important' | 'warning' | 'caution';\n\nconst TITLES: Record<string, string> = {\n note: 'Note',\n tip: 'Tip',\n important: 'Important',\n warning: 'Warning',\n caution: 'Caution',\n};\n\n/**\n * Default MDX `Admonition` component — the render target for the GitHub-style\n * `> [!NOTE]` blockquote-alert syntax (the transpiler remark plugin, R3-152,\n * compiles that syntax to `<Admonition type=\"note\">…</Admonition>`).\n *\n * It is registered in {@link DEFAULT_MDX_COMPONENTS} so an admonition renders\n * even in a plain-markdown repo that never calls `boot({ mdxComponents })` — the\n * MDX missing-reference guard never fires (MARKDOWN_SYNTAX_SPEC §11.2 phantom\n * defaults). The markup is semantic and accessible; **styling is intentionally\n * minimal** — an app supplies CSS targeting the `ir-admonition*` classes, or\n * overrides this component via `boot({ mdxComponents: { Admonition } })`\n * (MARKDOWN_SYNTAX_SPEC §12.3).\n */\nexport const Admonition = ({\n type = 'note',\n title,\n children,\n ...rest\n}: {\n type?: AdmonitionType | string;\n title?: ReactNode;\n children?: ReactNode;\n} & Omit<React.HTMLAttributes<HTMLDivElement>, 'title'>): ReactNode => {\n const kind = String(type).toLowerCase();\n const label = title ?? TITLES[kind] ?? TITLES.note;\n return (\n <div\n className={`ir-admonition ir-admonition-${kind}`}\n role=\"note\"\n data-admonition={kind}\n {...rest}\n >\n <p className=\"ir-admonition-title\">{label}</p>\n <div className=\"ir-admonition-body\">{children}</div>\n </div>\n );\n};\n"],"mappings":";AAuCI,SAME,KANF;AAlCJ,MAAM,SAAiC;AAAA,EACrC,MAAM;AAAA,EACN,KAAK;AAAA,EACL,WAAW;AAAA,EACX,SAAS;AAAA,EACT,SAAS;AACX;AAeO,MAAM,aAAa,CAAC;AAAA,EACzB,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAIuE;AACrE,QAAM,OAAO,OAAO,IAAI,EAAE,YAAY;AACtC,QAAM,QAAQ,SAAS,OAAO,IAAI,KAAK,OAAO;AAC9C,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,+BAA+B,IAAI;AAAA,MAC9C,MAAK;AAAA,MACL,mBAAiB;AAAA,MAChB,GAAG;AAAA,MAEJ;AAAA,4BAAC,OAAE,WAAU,uBAAuB,iBAAM;AAAA,QAC1C,oBAAC,SAAI,WAAU,sBAAsB,UAAS;AAAA;AAAA;AAAA,EAChD;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/Admonition.tsx"],"sourcesContent":["import { ReactNode } from 'react';\n\n/** The GitHub admonition kinds the transpiler's `> [!TYPE]` plugin emits (R3-152). */\nexport type AdmonitionType = 'note' | 'tip' | 'important' | 'warning' | 'caution';\n\nconst TITLES: Record<string, string> = {\n note: 'Note',\n tip: 'Tip',\n important: 'Important',\n warning: 'Warning',\n caution: 'Caution',\n};\n\n/**\n * Default MDX `Admonition` component — the render target for the GitHub-style\n * `> [!NOTE]` blockquote-alert syntax (the transpiler remark plugin, R3-152,\n * compiles that syntax to `<Admonition type=\"note\">…</Admonition>`).\n *\n * It is registered in {@link DEFAULT_MDX_COMPONENTS} so an admonition renders\n * even in a plain-markdown repo that never calls `boot({ mdxComponents })` — the\n * MDX missing-reference guard never fires (MARKDOWN_SYNTAX_SPEC §11.2 phantom\n * defaults). The markup is semantic and accessible; **styling is intentionally\n * minimal** — an app supplies CSS targeting the `ir-admonition*` classes, or\n * overrides this component via `boot({ mdxComponents: { Admonition } })`\n * (MARKDOWN_SYNTAX_SPEC §12.3).\n */\nexport const Admonition = ({\n type = 'note',\n title,\n children,\n ...rest\n}: {\n type?: AdmonitionType | string;\n title?: ReactNode;\n children?: ReactNode;\n} & Omit<React.HTMLAttributes<HTMLDivElement>, 'title'>): ReactNode => {\n const kind = String(type).toLowerCase();\n const label = title ?? TITLES[kind] ?? TITLES.note;\n return (\n <div className={`ir-admonition ir-admonition-${kind}`} role=\"note\" data-admonition={kind} {...rest}>\n <p className=\"ir-admonition-title\">{label}</p>\n <div className=\"ir-admonition-body\">{children}</div>\n </div>\n );\n};\n"],"mappings":";AAuCI,SACE,KADF;AAlCJ,MAAM,SAAiC;AAAA,EACrC,MAAM;AAAA,EACN,KAAK;AAAA,EACL,WAAW;AAAA,EACX,SAAS;AAAA,EACT,SAAS;AACX;AAeO,MAAM,aAAa,CAAC;AAAA,EACzB,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAIuE;AACrE,QAAM,OAAO,OAAO,IAAI,EAAE,YAAY;AACtC,QAAM,QAAQ,SAAS,OAAO,IAAI,KAAK,OAAO;AAC9C,SACE,qBAAC,SAAI,WAAW,+BAA+B,IAAI,IAAI,MAAK,QAAO,mBAAiB,MAAO,GAAG,MAC5F;AAAA,wBAAC,OAAE,WAAU,uBAAuB,iBAAM;AAAA,IAC1C,oBAAC,SAAI,WAAU,sBAAsB,UAAS;AAAA,KAChD;AAEJ;","names":[]}
@@ -31,11 +31,19 @@ const FileRouter = ({
31
31
  LoadingComponent = import_defaults.defaultLoadingComponent,
32
32
  ErrorComponent = import_defaults.defaultErrorComponent
33
33
  } = {}) => {
34
- const { navigationState: { pathParameters, sandboxPath } } = (0, import_react.useContext)(import_TinkerableContext.TinkerableContext);
34
+ const {
35
+ navigationState: { pathParameters, sandboxPath }
36
+ } = (0, import_react.useContext)(import_TinkerableContext.TinkerableContext);
35
37
  const filename = pathParameters?.["*"];
36
38
  if (!filename) {
37
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ErrorComponent, { error: new Error(`No filename could be extracted from ${sandboxPath}`), resetErrorBoundary: () => {
38
- } });
39
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
40
+ ErrorComponent,
41
+ {
42
+ error: new Error(`No filename could be extracted from ${sandboxPath}`),
43
+ resetErrorBoundary: () => {
44
+ }
45
+ }
46
+ );
39
47
  }
40
48
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
41
49
  import_Include.Include,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/FileRouter.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useContext } from 'react';\n\nimport { TinkerableContext } from '../TinkerableContext';\nimport { underAppRoot } from '../urlUtils';\nimport { defaultErrorComponent, defaultLoadingComponent } from './defaults';\nimport { Include } from './Include';\n\nexport const FileRouter: FC = ({\n LoadingComponent = defaultLoadingComponent,\n ErrorComponent = defaultErrorComponent,\n}: {\n LoadingComponent?: typeof defaultLoadingComponent;\n ErrorComponent?: typeof defaultErrorComponent;\n} = {}) => {\n const { navigationState: { pathParameters, sandboxPath } } = useContext(TinkerableContext);\n // The default table matches `/files/*`, surfacing the file path under the `*`\n // wildcard (SANDBOX_ROUTING_SPEC §4.1/§7).\n const filename = pathParameters?.['*'];\n if (!filename) {\n return <ErrorComponent error={new Error(`No filename could be extracted from ${sandboxPath}`)} resetErrorBoundary={() => {}}/>;\n }\n // URL subpaths are repo-relative; the sandbox fs is rooted at `/` with the\n // repo mounted at `APP_ROOT`, so anchor the file path there before resolving.\n return <Include\n filename={underAppRoot(filename)}\n LoadingComponent={LoadingComponent}\n ErrorComponent={ErrorComponent}\n // @ts-ignore\n baseModule={module}\n />\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAoBW;AAnBX,mBAA2B;AAE3B,+BAAkC;AAClC,sBAA6B;AAC7B,sBAA+D;AAC/D,qBAAwB;AAEjB,MAAM,aAAiB,CAAC;AAAA,EAC7B,mBAAmB;AAAA,EACnB,iBAAiB;AACnB,IAGI,CAAC,MAAM;AACT,QAAM,EAAE,iBAAiB,EAAE,gBAAgB,YAAY,EAAE,QAAI,yBAAW,0CAAiB;AAGzF,QAAM,WAAW,iBAAiB,GAAG;AACrC,MAAI,CAAC,UAAU;AACb,WAAO,4CAAC,kBAAe,OAAO,IAAI,MAAM,uCAAuC,WAAW,EAAE,GAAG,oBAAoB,MAAM;AAAA,IAAC,GAAE;AAAA,EAC9H;AAGA,SAAO;AAAA,IAAC;AAAA;AAAA,MACN,cAAU,8BAAa,QAAQ;AAAA,MAC/B;AAAA,MACA;AAAA,MAEA,YAAY;AAAA;AAAA,EACd;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/components/FileRouter.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useContext } from 'react';\n\nimport { TinkerableContext } from '../TinkerableContext';\nimport { underAppRoot } from '../urlUtils';\nimport { defaultErrorComponent, defaultLoadingComponent } from './defaults';\nimport { Include } from './Include';\n\nexport const FileRouter: FC = ({\n LoadingComponent = defaultLoadingComponent,\n ErrorComponent = defaultErrorComponent,\n}: {\n LoadingComponent?: typeof defaultLoadingComponent;\n ErrorComponent?: typeof defaultErrorComponent;\n} = {}) => {\n const {\n navigationState: { pathParameters, sandboxPath },\n } = useContext(TinkerableContext);\n // The default table matches `/files/*`, surfacing the file path under the `*`\n // wildcard (SANDBOX_ROUTING_SPEC §4.1/§7).\n const filename = pathParameters?.['*'];\n if (!filename) {\n return (\n <ErrorComponent\n error={new Error(`No filename could be extracted from ${sandboxPath}`)}\n resetErrorBoundary={() => {}}\n />\n );\n }\n // URL subpaths are repo-relative; the sandbox fs is rooted at `/` with the\n // repo mounted at `APP_ROOT`, so anchor the file path there before resolving.\n return (\n <Include\n filename={underAppRoot(filename)}\n LoadingComponent={LoadingComponent}\n ErrorComponent={ErrorComponent}\n // @ts-ignore\n baseModule={module}\n />\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAuBM;AAtBN,mBAA2B;AAE3B,+BAAkC;AAClC,sBAA6B;AAC7B,sBAA+D;AAC/D,qBAAwB;AAEjB,MAAM,aAAiB,CAAC;AAAA,EAC7B,mBAAmB;AAAA,EACnB,iBAAiB;AACnB,IAGI,CAAC,MAAM;AACT,QAAM;AAAA,IACJ,iBAAiB,EAAE,gBAAgB,YAAY;AAAA,EACjD,QAAI,yBAAW,0CAAiB;AAGhC,QAAM,WAAW,iBAAiB,GAAG;AACrC,MAAI,CAAC,UAAU;AACb,WACE;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,IAAI,MAAM,uCAAuC,WAAW,EAAE;AAAA,QACrE,oBAAoB,MAAM;AAAA,QAAC;AAAA;AAAA,IAC7B;AAAA,EAEJ;AAGA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,cAAU,8BAAa,QAAQ;AAAA,MAC/B;AAAA,MACA;AAAA,MAEA,YAAY;AAAA;AAAA,EACd;AAEJ;","names":[]}
@@ -9,11 +9,19 @@ const FileRouter = ({
9
9
  LoadingComponent = defaultLoadingComponent,
10
10
  ErrorComponent = defaultErrorComponent
11
11
  } = {}) => {
12
- const { navigationState: { pathParameters, sandboxPath } } = useContext(TinkerableContext);
12
+ const {
13
+ navigationState: { pathParameters, sandboxPath }
14
+ } = useContext(TinkerableContext);
13
15
  const filename = pathParameters?.["*"];
14
16
  if (!filename) {
15
- return /* @__PURE__ */ jsx(ErrorComponent, { error: new Error(`No filename could be extracted from ${sandboxPath}`), resetErrorBoundary: () => {
16
- } });
17
+ return /* @__PURE__ */ jsx(
18
+ ErrorComponent,
19
+ {
20
+ error: new Error(`No filename could be extracted from ${sandboxPath}`),
21
+ resetErrorBoundary: () => {
22
+ }
23
+ }
24
+ );
17
25
  }
18
26
  return /* @__PURE__ */ jsx(
19
27
  Include,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/FileRouter.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useContext } from 'react';\n\nimport { TinkerableContext } from '../TinkerableContext';\nimport { underAppRoot } from '../urlUtils';\nimport { defaultErrorComponent, defaultLoadingComponent } from './defaults';\nimport { Include } from './Include';\n\nexport const FileRouter: FC = ({\n LoadingComponent = defaultLoadingComponent,\n ErrorComponent = defaultErrorComponent,\n}: {\n LoadingComponent?: typeof defaultLoadingComponent;\n ErrorComponent?: typeof defaultErrorComponent;\n} = {}) => {\n const { navigationState: { pathParameters, sandboxPath } } = useContext(TinkerableContext);\n // The default table matches `/files/*`, surfacing the file path under the `*`\n // wildcard (SANDBOX_ROUTING_SPEC §4.1/§7).\n const filename = pathParameters?.['*'];\n if (!filename) {\n return <ErrorComponent error={new Error(`No filename could be extracted from ${sandboxPath}`)} resetErrorBoundary={() => {}}/>;\n }\n // URL subpaths are repo-relative; the sandbox fs is rooted at `/` with the\n // repo mounted at `APP_ROOT`, so anchor the file path there before resolving.\n return <Include\n filename={underAppRoot(filename)}\n LoadingComponent={LoadingComponent}\n ErrorComponent={ErrorComponent}\n // @ts-ignore\n baseModule={module}\n />\n};\n"],"mappings":";AAoBW;AAnBX,SAAS,kBAAkB;AAE3B,SAAS,yBAAyB;AAClC,SAAS,oBAAoB;AAC7B,SAAS,uBAAuB,+BAA+B;AAC/D,SAAS,eAAe;AAEjB,MAAM,aAAiB,CAAC;AAAA,EAC7B,mBAAmB;AAAA,EACnB,iBAAiB;AACnB,IAGI,CAAC,MAAM;AACT,QAAM,EAAE,iBAAiB,EAAE,gBAAgB,YAAY,EAAE,IAAI,WAAW,iBAAiB;AAGzF,QAAM,WAAW,iBAAiB,GAAG;AACrC,MAAI,CAAC,UAAU;AACb,WAAO,oBAAC,kBAAe,OAAO,IAAI,MAAM,uCAAuC,WAAW,EAAE,GAAG,oBAAoB,MAAM;AAAA,IAAC,GAAE;AAAA,EAC9H;AAGA,SAAO;AAAA,IAAC;AAAA;AAAA,MACN,UAAU,aAAa,QAAQ;AAAA,MAC/B;AAAA,MACA;AAAA,MAEA,YAAY;AAAA;AAAA,EACd;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/components/FileRouter.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useContext } from 'react';\n\nimport { TinkerableContext } from '../TinkerableContext';\nimport { underAppRoot } from '../urlUtils';\nimport { defaultErrorComponent, defaultLoadingComponent } from './defaults';\nimport { Include } from './Include';\n\nexport const FileRouter: FC = ({\n LoadingComponent = defaultLoadingComponent,\n ErrorComponent = defaultErrorComponent,\n}: {\n LoadingComponent?: typeof defaultLoadingComponent;\n ErrorComponent?: typeof defaultErrorComponent;\n} = {}) => {\n const {\n navigationState: { pathParameters, sandboxPath },\n } = useContext(TinkerableContext);\n // The default table matches `/files/*`, surfacing the file path under the `*`\n // wildcard (SANDBOX_ROUTING_SPEC §4.1/§7).\n const filename = pathParameters?.['*'];\n if (!filename) {\n return (\n <ErrorComponent\n error={new Error(`No filename could be extracted from ${sandboxPath}`)}\n resetErrorBoundary={() => {}}\n />\n );\n }\n // URL subpaths are repo-relative; the sandbox fs is rooted at `/` with the\n // repo mounted at `APP_ROOT`, so anchor the file path there before resolving.\n return (\n <Include\n filename={underAppRoot(filename)}\n LoadingComponent={LoadingComponent}\n ErrorComponent={ErrorComponent}\n // @ts-ignore\n baseModule={module}\n />\n );\n};\n"],"mappings":";AAuBM;AAtBN,SAAS,kBAAkB;AAE3B,SAAS,yBAAyB;AAClC,SAAS,oBAAoB;AAC7B,SAAS,uBAAuB,+BAA+B;AAC/D,SAAS,eAAe;AAEjB,MAAM,aAAiB,CAAC;AAAA,EAC7B,mBAAmB;AAAA,EACnB,iBAAiB;AACnB,IAGI,CAAC,MAAM;AACT,QAAM;AAAA,IACJ,iBAAiB,EAAE,gBAAgB,YAAY;AAAA,EACjD,IAAI,WAAW,iBAAiB;AAGhC,QAAM,WAAW,iBAAiB,GAAG;AACrC,MAAI,CAAC,UAAU;AACb,WACE;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,IAAI,MAAM,uCAAuC,WAAW,EAAE;AAAA,QACrE,oBAAoB,MAAM;AAAA,QAAC;AAAA;AAAA,IAC7B;AAAA,EAEJ;AAGA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,UAAU,aAAa,QAAQ;AAAA,MAC/B;AAAA,MACA;AAAA,MAEA,YAAY;AAAA;AAAA,EACd;AAEJ;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/HeadingAnchor.tsx"],"sourcesContent":["import { ReactNode, use, useCallback } from 'react';\nimport { scrollToId } from '../scrollToId';\nimport { TinkerableContext } from '../TinkerableContext';\nimport { constructOuterUrl } from '../urlUtils';\nimport { FragmentLink } from './Link';\n\n/**\n * Default MDX `HeadingAnchor` component — the render target for the autolink anchor\n * the transpiler's heading-slug plugin (R3-186, `MARKDOWN_SYNTAX_SPEC §15.4`)\n * prepends to every heading. That plugin sets the heading's own `id` (a text slug,\n * or a `sec-…` section id for a numbered heading, R3-211) and emits\n * `<HeadingAnchor id=\"<that id>\" />` as the heading's first child.\n *\n * It is registered in {@link DEFAULT_MDX_COMPONENTS} so a heading anchor renders\n * even in a plain-markdown repo that never calls `boot({ mdxComponents })` — the\n * MDX missing-reference guard never fires (§11.2 phantom defaults). The markup is\n * semantic and accessible — an `aria`-labelled `<a href=\"#id\">` permalink — but\n * **styling is intentionally minimal** (`§15.4` honesty note): an app supplies CSS\n * targeting the `ir-heading-anchor` class to reveal it on hover / add an icon, or\n * overrides this component via `boot({ mdxComponents: { HeadingAnchor } })` to\n * change the icon, position, or behaviour (e.g. copy-permalink-to-clipboard) of\n * every heading anchor in every content file at once (§15.4 late binding).\n *\n * `id` is the *heading's own* id, so the permalink `#id` is the same URL a reader\n * copies and (for a `sec-…` id) an agent computes from a `§`-citation with zero\n * lookup. A missing/empty `id` (defensive — the plugin always supplies one)\n * renders nothing rather than a dead `#` link.\n */\nexport const HeadingAnchor = ({\n id,\n ...rest\n}: {\n id?: string;\n} & Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, 'href'>): ReactNode => {\n // ⚠ A BARE `#id` IS THE WRONG HREF INSIDE A SANDBOXED APP, and wrong in a way that only\n // shows up when someone copies the link. The app runs in an iframe whose document URL is\n // the SANDBOX's (`https://sandbox.immediately.run/index.html?href=…`), so the browser\n // resolves `#id` against THAT — \"copy link address\" on a heading yields a\n // sandbox-internal URL that means nothing to anyone else. Reported from a real wiki\n // (2026-08-14) as exactly that URL instead of the entry's.\n //\n // Both halves have to be right, and they pull in opposite directions:\n // • the HREF must be absolute in the HOST's space, so copy-link / middle-click /\n // open-in-new-tab all produce a URL that resolves for a reader;\n // • the CLICK must NOT navigate to it — that would be a full page load to the page you\n // are already on. It scrolls, leaving the sandbox URL the host owns untouched.\n //\n // `FragmentLink` is the SDK's existing home for the second half; it runs the caller's\n // `onClick` first and stands down if it preventDefaults, which is what lets the href be\n // absolute here while the behaviour stays a scroll.\n const ctx = use(TinkerableContext);\n const onAnchorClick = useCallback(\n (e: React.MouseEvent<HTMLAnchorElement>) => {\n // Let a modified click through: cmd/ctrl/middle-click means \"open the permalink\",\n // and that is precisely the case the absolute href exists to serve.\n if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey || e.button !== 0) return;\n e.preventDefault();\n if (id) scrollToId(id);\n },\n [id]\n );\n if (!id) return null;\n // No context (a plain-markdown repo that never called `boot()`) → keep the old bare\n // fragment, which FragmentLink handles on its own.\n const href = ctx?.navigationState\n ? constructOuterUrl(ctx.outerHref, `#${id}`, ctx.navigationState)\n : `#${id}`;\n return (\n <FragmentLink\n className=\"ir-heading-anchor\"\n href={href}\n onClick={onAnchorClick}\n aria-label=\"Permalink to this heading\"\n {...rest}\n >\n <span aria-hidden=\"true\">#</span>\n </FragmentLink>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA2EM;AA3EN,mBAA4C;AAC5C,wBAA2B;AAC3B,+BAAkC;AAClC,sBAAkC;AAClC,kBAA6B;AAwBtB,MAAM,gBAAgB,CAAC;AAAA,EAC5B;AAAA,EACA,GAAG;AACL,MAE+E;AAiB7E,QAAM,UAAM,kBAAI,0CAAiB;AACjC,QAAM,oBAAgB;AAAA,IACpB,CAAC,MAA2C;AAG1C,UAAI,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAG;AACxE,QAAE,eAAe;AACjB,UAAI,GAAI,mCAAW,EAAE;AAAA,IACvB;AAAA,IACA,CAAC,EAAE;AAAA,EACL;AACA,MAAI,CAAC,GAAI,QAAO;AAGhB,QAAM,OAAO,KAAK,sBACd,mCAAkB,IAAI,WAAW,IAAI,EAAE,IAAI,IAAI,eAAe,IAC9D,IAAI,EAAE;AACV,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV;AAAA,MACA,SAAS;AAAA,MACT,cAAW;AAAA,MACV,GAAG;AAAA,MAEJ,sDAAC,UAAK,eAAY,QAAO,eAAC;AAAA;AAAA,EAC5B;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/HeadingAnchor.tsx"],"sourcesContent":["import { ReactNode, use, useCallback } from 'react';\nimport { scrollToId } from '../scrollToId';\nimport { TinkerableContext } from '../TinkerableContext';\nimport { constructOuterUrl } from '../urlUtils';\nimport { FragmentLink } from './Link';\n\n/**\n * Default MDX `HeadingAnchor` component — the render target for the autolink anchor\n * the transpiler's heading-slug plugin (R3-186, `MARKDOWN_SYNTAX_SPEC §15.4`)\n * prepends to every heading. That plugin sets the heading's own `id` (a text slug,\n * or a `sec-…` section id for a numbered heading, R3-211) and emits\n * `<HeadingAnchor id=\"<that id>\" />` as the heading's first child.\n *\n * It is registered in {@link DEFAULT_MDX_COMPONENTS} so a heading anchor renders\n * even in a plain-markdown repo that never calls `boot({ mdxComponents })` — the\n * MDX missing-reference guard never fires (§11.2 phantom defaults). The markup is\n * semantic and accessible — an `aria`-labelled `<a href=\"#id\">` permalink — but\n * **styling is intentionally minimal** (`§15.4` honesty note): an app supplies CSS\n * targeting the `ir-heading-anchor` class to reveal it on hover / add an icon, or\n * overrides this component via `boot({ mdxComponents: { HeadingAnchor } })` to\n * change the icon, position, or behaviour (e.g. copy-permalink-to-clipboard) of\n * every heading anchor in every content file at once (§15.4 late binding).\n *\n * `id` is the *heading's own* id, so the permalink `#id` is the same URL a reader\n * copies and (for a `sec-…` id) an agent computes from a `§`-citation with zero\n * lookup. A missing/empty `id` (defensive — the plugin always supplies one)\n * renders nothing rather than a dead `#` link.\n */\nexport const HeadingAnchor = ({\n id,\n ...rest\n}: {\n id?: string;\n} & Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, 'href'>): ReactNode => {\n // ⚠ A BARE `#id` IS THE WRONG HREF INSIDE A SANDBOXED APP, and wrong in a way that only\n // shows up when someone copies the link. The app runs in an iframe whose document URL is\n // the SANDBOX's (`https://sandbox.immediately.run/index.html?href=…`), so the browser\n // resolves `#id` against THAT — \"copy link address\" on a heading yields a\n // sandbox-internal URL that means nothing to anyone else. Reported from a real wiki\n // (2026-08-14) as exactly that URL instead of the entry's.\n //\n // Both halves have to be right, and they pull in opposite directions:\n // • the HREF must be absolute in the HOST's space, so copy-link / middle-click /\n // open-in-new-tab all produce a URL that resolves for a reader;\n // • the CLICK must NOT navigate to it — that would be a full page load to the page you\n // are already on. It scrolls, leaving the sandbox URL the host owns untouched.\n //\n // `FragmentLink` is the SDK's existing home for the second half; it runs the caller's\n // `onClick` first and stands down if it preventDefaults, which is what lets the href be\n // absolute here while the behaviour stays a scroll.\n const ctx = use(TinkerableContext);\n const onAnchorClick = useCallback(\n (e: React.MouseEvent<HTMLAnchorElement>) => {\n // Let a modified click through: cmd/ctrl/middle-click means \"open the permalink\",\n // and that is precisely the case the absolute href exists to serve.\n if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey || e.button !== 0) return;\n e.preventDefault();\n if (id) scrollToId(id);\n },\n [id],\n );\n if (!id) return null;\n // No context (a plain-markdown repo that never called `boot()`) → keep the old bare\n // fragment, which FragmentLink handles on its own.\n const href = ctx?.navigationState ? constructOuterUrl(ctx.outerHref, `#${id}`, ctx.navigationState) : `#${id}`;\n return (\n <FragmentLink\n className=\"ir-heading-anchor\"\n href={href}\n onClick={onAnchorClick}\n aria-label=\"Permalink to this heading\"\n {...rest}\n >\n <span aria-hidden=\"true\">#</span>\n </FragmentLink>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAyEM;AAzEN,mBAA4C;AAC5C,wBAA2B;AAC3B,+BAAkC;AAClC,sBAAkC;AAClC,kBAA6B;AAwBtB,MAAM,gBAAgB,CAAC;AAAA,EAC5B;AAAA,EACA,GAAG;AACL,MAE+E;AAiB7E,QAAM,UAAM,kBAAI,0CAAiB;AACjC,QAAM,oBAAgB;AAAA,IACpB,CAAC,MAA2C;AAG1C,UAAI,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAG;AACxE,QAAE,eAAe;AACjB,UAAI,GAAI,mCAAW,EAAE;AAAA,IACvB;AAAA,IACA,CAAC,EAAE;AAAA,EACL;AACA,MAAI,CAAC,GAAI,QAAO;AAGhB,QAAM,OAAO,KAAK,sBAAkB,mCAAkB,IAAI,WAAW,IAAI,EAAE,IAAI,IAAI,eAAe,IAAI,IAAI,EAAE;AAC5G,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV;AAAA,MACA,SAAS;AAAA,MACT,cAAW;AAAA,MACV,GAAG;AAAA,MAEJ,sDAAC,UAAK,eAAY,QAAO,eAAC;AAAA;AAAA,EAC5B;AAEJ;","names":[]}