@kestack/kabuki 0.0.1 → 0.0.2

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 (234) hide show
  1. package/README.md +156 -33
  2. package/dist/core/actor/actor.d.ts +24 -13
  3. package/dist/core/actor/actor.d.ts.map +1 -1
  4. package/dist/core/actor/actor.js +37 -26
  5. package/dist/core/actor/index.d.ts +2 -2
  6. package/dist/core/actor/index.d.ts.map +1 -1
  7. package/dist/core/actor/types.d.ts +91 -47
  8. package/dist/core/actor/types.d.ts.map +1 -1
  9. package/dist/core/history/history.d.ts +11 -3
  10. package/dist/core/history/history.d.ts.map +1 -1
  11. package/dist/core/history/history.js +106 -27
  12. package/dist/core/history/replay.d.ts +2 -0
  13. package/dist/core/history/replay.d.ts.map +1 -1
  14. package/dist/core/history/replay.js +1 -0
  15. package/dist/core/history/saved.d.ts +1 -1
  16. package/dist/core/history/saved.d.ts.map +1 -1
  17. package/dist/core/history/saved.js +13 -9
  18. package/dist/core/index.d.ts +1 -1
  19. package/dist/core/index.d.ts.map +1 -1
  20. package/dist/core/snapshot/invoke.d.ts +2 -3
  21. package/dist/core/snapshot/invoke.d.ts.map +1 -1
  22. package/dist/core/snapshot/invoke.js +42 -49
  23. package/dist/core/snapshot/restore.js +8 -7
  24. package/dist/core/snapshot/tree.d.ts +1 -1
  25. package/dist/core/snapshot/tree.d.ts.map +1 -1
  26. package/dist/core/snapshot/tree.js +1 -1
  27. package/dist/react/app.d.ts +30 -3
  28. package/dist/react/app.d.ts.map +1 -1
  29. package/dist/react/app.js +119 -40
  30. package/dist/react/drawn.d.ts +1 -1
  31. package/dist/react/drawn.d.ts.map +1 -1
  32. package/dist/react/drawn.js +2 -1
  33. package/dist/react/index.d.ts +3 -0
  34. package/dist/react/index.d.ts.map +1 -1
  35. package/dist/react/index.js +2 -0
  36. package/dist/react/lazy.d.ts +30 -0
  37. package/dist/react/lazy.d.ts.map +1 -0
  38. package/dist/react/lazy.js +56 -0
  39. package/dist/react/live.d.ts +7 -0
  40. package/dist/react/live.d.ts.map +1 -0
  41. package/dist/react/live.js +13 -0
  42. package/dist/react/view.d.ts +26 -6
  43. package/dist/react/view.d.ts.map +1 -1
  44. package/dist/react/view.js +17 -5
  45. package/dist/routing/adapter/adapter.d.ts +38 -0
  46. package/dist/routing/adapter/adapter.d.ts.map +1 -0
  47. package/dist/routing/adapter/adapter.js +10 -0
  48. package/dist/routing/adapter/browser/browser.d.ts +8 -0
  49. package/dist/routing/adapter/browser/browser.d.ts.map +1 -0
  50. package/dist/routing/adapter/browser/browser.js +33 -0
  51. package/dist/routing/adapter/browser/index.d.ts +2 -0
  52. package/dist/routing/adapter/browser/index.d.ts.map +1 -0
  53. package/dist/routing/adapter/browser/index.js +1 -0
  54. package/dist/routing/adapter/index.d.ts +3 -0
  55. package/dist/routing/adapter/index.d.ts.map +1 -0
  56. package/dist/routing/adapter/index.js +1 -0
  57. package/dist/routing/adapter/tanstack/index.d.ts +3 -0
  58. package/dist/routing/adapter/tanstack/index.d.ts.map +1 -0
  59. package/dist/routing/adapter/tanstack/index.js +1 -0
  60. package/dist/routing/adapter/tanstack/tanstack.d.ts +27 -0
  61. package/dist/routing/adapter/tanstack/tanstack.d.ts.map +1 -0
  62. package/dist/routing/adapter/tanstack/tanstack.js +38 -0
  63. package/dist/routing/capability/cache.d.ts +12 -0
  64. package/dist/routing/capability/cache.d.ts.map +1 -0
  65. package/dist/routing/capability/cache.js +170 -0
  66. package/dist/routing/capability/index.d.ts +6 -0
  67. package/dist/routing/capability/index.d.ts.map +1 -0
  68. package/dist/routing/capability/index.js +3 -0
  69. package/dist/routing/capability/loading.d.ts +82 -0
  70. package/dist/routing/capability/loading.d.ts.map +1 -0
  71. package/dist/routing/capability/loading.js +53 -0
  72. package/dist/routing/capability/navigation.d.ts +66 -0
  73. package/dist/routing/capability/navigation.d.ts.map +1 -0
  74. package/dist/routing/capability/navigation.js +65 -0
  75. package/dist/routing/index.d.ts +10 -0
  76. package/dist/routing/index.d.ts.map +1 -0
  77. package/dist/routing/index.js +4 -0
  78. package/dist/routing/page/index.d.ts +5 -0
  79. package/dist/routing/page/index.d.ts.map +1 -0
  80. package/dist/routing/page/index.js +2 -0
  81. package/dist/routing/page/page.d.ts +151 -0
  82. package/dist/routing/page/page.d.ts.map +1 -0
  83. package/dist/routing/page/page.js +121 -0
  84. package/dist/routing/page/status.d.ts +121 -0
  85. package/dist/routing/page/status.d.ts.map +1 -0
  86. package/dist/routing/page/status.js +69 -0
  87. package/dist/routing/route/index.d.ts +11 -0
  88. package/dist/routing/route/index.d.ts.map +1 -0
  89. package/dist/routing/route/index.js +6 -0
  90. package/dist/routing/route/loader.d.ts +98 -0
  91. package/dist/routing/route/loader.d.ts.map +1 -0
  92. package/dist/routing/route/loader.js +17 -0
  93. package/dist/routing/route/metadata.d.ts +44 -0
  94. package/dist/routing/route/metadata.d.ts.map +1 -0
  95. package/dist/routing/route/metadata.js +53 -0
  96. package/dist/routing/route/node.d.ts +162 -0
  97. package/dist/routing/route/node.d.ts.map +1 -0
  98. package/dist/routing/route/node.js +3 -0
  99. package/dist/routing/route/places.d.ts +15 -0
  100. package/dist/routing/route/places.d.ts.map +1 -0
  101. package/dist/routing/route/places.js +87 -0
  102. package/dist/routing/route/route.d.ts +53 -0
  103. package/dist/routing/route/route.d.ts.map +1 -0
  104. package/dist/routing/route/route.js +148 -0
  105. package/dist/routing/route/url.d.ts +13 -0
  106. package/dist/routing/route/url.d.ts.map +1 -0
  107. package/dist/routing/route/url.js +79 -0
  108. package/dist/routing/route/values.d.ts +12 -0
  109. package/dist/routing/route/values.d.ts.map +1 -0
  110. package/dist/routing/route/values.js +47 -0
  111. package/dist/routing/router/context.d.ts +123 -0
  112. package/dist/routing/router/context.d.ts.map +1 -0
  113. package/dist/routing/router/context.js +156 -0
  114. package/dist/routing/router/data.d.ts +117 -0
  115. package/dist/routing/router/data.d.ts.map +1 -0
  116. package/dist/routing/router/data.js +247 -0
  117. package/dist/routing/router/define.d.ts +52 -0
  118. package/dist/routing/router/define.d.ts.map +1 -0
  119. package/dist/routing/router/define.js +48 -0
  120. package/dist/routing/router/frame.d.ts +10 -0
  121. package/dist/routing/router/frame.d.ts.map +1 -0
  122. package/dist/routing/router/frame.js +10 -0
  123. package/dist/routing/router/index.d.ts +7 -0
  124. package/dist/routing/router/index.d.ts.map +1 -0
  125. package/dist/routing/router/index.js +3 -0
  126. package/dist/routing/router/router.d.ts +165 -0
  127. package/dist/routing/router/router.d.ts.map +1 -0
  128. package/dist/routing/router/router.js +801 -0
  129. package/dist/routing/routing.d.ts +72 -0
  130. package/dist/routing/routing.d.ts.map +1 -0
  131. package/dist/routing/routing.js +53 -0
  132. package/dist/routing/scroll/index.d.ts +4 -0
  133. package/dist/routing/scroll/index.d.ts.map +1 -0
  134. package/dist/routing/scroll/index.js +2 -0
  135. package/dist/routing/scroll/script.d.ts +6 -0
  136. package/dist/routing/scroll/script.d.ts.map +1 -0
  137. package/dist/routing/scroll/script.js +52 -0
  138. package/dist/routing/scroll/scroll.d.ts +75 -0
  139. package/dist/routing/scroll/scroll.d.ts.map +1 -0
  140. package/dist/routing/scroll/scroll.js +201 -0
  141. package/dist/routing/scroll/selector.d.ts +14 -0
  142. package/dist/routing/scroll/selector.d.ts.map +1 -0
  143. package/dist/routing/scroll/selector.js +40 -0
  144. package/dist/routing/scroll/session.d.ts +6 -0
  145. package/dist/routing/scroll/session.d.ts.map +1 -0
  146. package/dist/routing/scroll/session.js +23 -0
  147. package/dist/start/client/client.d.ts +11 -0
  148. package/dist/start/client/client.d.ts.map +1 -0
  149. package/dist/start/client/client.js +24 -0
  150. package/dist/start/client/index.d.ts +3 -0
  151. package/dist/start/client/index.d.ts.map +1 -0
  152. package/dist/start/client/index.js +2 -0
  153. package/dist/start/client/rpc.d.ts +14 -0
  154. package/dist/start/client/rpc.d.ts.map +1 -0
  155. package/dist/start/client/rpc.js +70 -0
  156. package/dist/start/common/app.d.ts +66 -0
  157. package/dist/start/common/app.d.ts.map +1 -0
  158. package/dist/start/common/app.js +23 -0
  159. package/dist/start/common/common.d.ts +26 -0
  160. package/dist/start/common/common.d.ts.map +1 -0
  161. package/dist/start/common/common.js +19 -0
  162. package/dist/start/common/document.d.ts +44 -0
  163. package/dist/start/common/document.d.ts.map +1 -0
  164. package/dist/start/common/document.js +58 -0
  165. package/dist/start/common/index.d.ts +9 -0
  166. package/dist/start/common/index.d.ts.map +1 -0
  167. package/dist/start/common/index.js +5 -0
  168. package/dist/start/common/page.d.ts +67 -0
  169. package/dist/start/common/page.d.ts.map +1 -0
  170. package/dist/start/common/page.js +29 -0
  171. package/dist/start/common/wire.d.ts +37 -0
  172. package/dist/start/common/wire.d.ts.map +1 -0
  173. package/dist/start/common/wire.js +73 -0
  174. package/dist/start/platform/cloudflare/cloudflare.d.ts +8 -0
  175. package/dist/start/platform/cloudflare/cloudflare.d.ts.map +1 -0
  176. package/dist/start/platform/cloudflare/cloudflare.js +31 -0
  177. package/dist/start/platform/cloudflare/index.d.ts +2 -0
  178. package/dist/start/platform/cloudflare/index.d.ts.map +1 -0
  179. package/dist/start/platform/cloudflare/index.js +1 -0
  180. package/dist/start/platform/index.d.ts +2 -0
  181. package/dist/start/platform/index.d.ts.map +1 -0
  182. package/dist/start/platform/index.js +1 -0
  183. package/dist/start/platform/platform.d.ts +31 -0
  184. package/dist/start/platform/platform.d.ts.map +1 -0
  185. package/dist/start/platform/platform.js +13 -0
  186. package/dist/start/server/cache.d.ts +4 -0
  187. package/dist/start/server/cache.d.ts.map +1 -0
  188. package/dist/start/server/cache.js +26 -0
  189. package/dist/start/server/draw.d.ts +10 -0
  190. package/dist/start/server/draw.d.ts.map +1 -0
  191. package/dist/start/server/draw.js +75 -0
  192. package/dist/start/server/index.d.ts +3 -0
  193. package/dist/start/server/index.d.ts.map +1 -0
  194. package/dist/start/server/index.js +2 -0
  195. package/dist/start/server/layers.d.ts +97 -0
  196. package/dist/start/server/layers.d.ts.map +1 -0
  197. package/dist/start/server/layers.js +37 -0
  198. package/dist/start/server/respond.d.ts +15 -0
  199. package/dist/start/server/respond.d.ts.map +1 -0
  200. package/dist/start/server/respond.js +35 -0
  201. package/dist/start/server/rpc.d.ts +11 -0
  202. package/dist/start/server/rpc.d.ts.map +1 -0
  203. package/dist/start/server/rpc.js +51 -0
  204. package/dist/start/server/server.d.ts +13 -0
  205. package/dist/start/server/server.d.ts.map +1 -0
  206. package/dist/start/server/server.js +138 -0
  207. package/dist/start/server/tiers.d.ts +14 -0
  208. package/dist/start/server/tiers.d.ts.map +1 -0
  209. package/dist/start/server/tiers.js +31 -0
  210. package/dist/start/vite/dev.d.ts +5 -0
  211. package/dist/start/vite/dev.d.ts.map +1 -0
  212. package/dist/start/vite/dev.js +56 -0
  213. package/dist/start/vite/entries.d.ts +27 -0
  214. package/dist/start/vite/entries.d.ts.map +1 -0
  215. package/dist/start/vite/entries.js +66 -0
  216. package/dist/start/vite/files.d.ts +22 -0
  217. package/dist/start/vite/files.d.ts.map +1 -0
  218. package/dist/start/vite/files.js +23 -0
  219. package/dist/start/vite/index.d.ts +2 -0
  220. package/dist/start/vite/index.d.ts.map +1 -0
  221. package/dist/start/vite/index.js +1 -0
  222. package/dist/start/vite/lazy.d.ts +4 -0
  223. package/dist/start/vite/lazy.d.ts.map +1 -0
  224. package/dist/start/vite/lazy.js +30 -0
  225. package/dist/start/vite/manifest.d.ts +18 -0
  226. package/dist/start/vite/manifest.d.ts.map +1 -0
  227. package/dist/start/vite/manifest.js +42 -0
  228. package/dist/start/vite/styles.d.ts +7 -0
  229. package/dist/start/vite/styles.d.ts.map +1 -0
  230. package/dist/start/vite/styles.js +58 -0
  231. package/dist/start/vite/vite.d.ts +11 -0
  232. package/dist/start/vite/vite.d.ts.map +1 -0
  233. package/dist/start/vite/vite.js +217 -0
  234. package/package.json +53 -3
@@ -0,0 +1,14 @@
1
+ import { Layer } from 'effect';
2
+ import { Loading } from '../../routing/index.ts';
3
+ import type { RoutesOnWire } from '../common/index.ts';
4
+ /**
5
+ * The browser's side: a `Loading` that asks the server, in one request per
6
+ * ask, and hands on each place's answer as it comes. A request that does
7
+ * not get an answer breaks every place it asked for, so each page shows it
8
+ * failed and can retry.
9
+ */
10
+ export declare const loading: (routes: RoutesOnWire, options?: {
11
+ readonly fetch?: typeof fetch;
12
+ readonly url?: string;
13
+ }) => Layer.Layer<Loading>;
14
+ //# sourceMappingURL=rpc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc.d.ts","sourceRoot":"","sources":["../../../src/start/client/rpc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,EAAU,MAAM,QAAQ,CAAC;AACtD,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAGjD,OAAO,KAAK,EAAQ,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAQ7D;;;;;GAKG;AACH,eAAO,MAAM,OAAO,WACV,YAAY,YACX;IAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,KAChE,KAAK,CAAC,KAAK,CAAC,OAAO,CAkFrB,CAAC"}
@@ -0,0 +1,70 @@
1
+ import { Cause, Effect, Layer, Stream } from 'effect';
2
+ import { Loading } from '../../routing/index.js';
3
+ import { PATH, loadable, readLine, writeAsk } from '../common/index.js';
4
+ /*
5
+ * The Loader RPC, asked: the `Loading` behind the browser's Data cache, one
6
+ * request for every place asked for at once, each answered as its line
7
+ * comes. The protocol is `common/wire.ts`.
8
+ */
9
+ /**
10
+ * The browser's side: a `Loading` that asks the server, in one request per
11
+ * ask, and hands on each place's answer as it comes. A request that does
12
+ * not get an answer breaks every place it asked for, so each page shows it
13
+ * failed and can retry.
14
+ */
15
+ export const loading = (routes, options = {}) => {
16
+ const places = loadable(routes);
17
+ const send = options.fetch ?? ((input, init) => fetch(input, init));
18
+ const each = (wanted) => {
19
+ const answered = new Set();
20
+ let broken;
21
+ return Stream.unwrap(Effect.gen(function* () {
22
+ const response = yield* Effect.tryPromise({
23
+ try: (signal) => send(options.url ?? PATH, {
24
+ method: 'POST',
25
+ headers: { 'content-type': 'application/json' },
26
+ body: JSON.stringify(writeAsk(places, wanted)),
27
+ signal,
28
+ }),
29
+ catch: (cause) => cause,
30
+ });
31
+ if (!response.ok || !response.body)
32
+ return yield* Effect.fail(new Error(`the Loader RPC answered ${response.status}`));
33
+ return Stream.fromReadableStream({
34
+ evaluate: () => response.body,
35
+ onError: (cause) => cause,
36
+ }).pipe(Stream.decodeText(), Stream.splitLines, Stream.filter((line) => line.trim() !== ''), Stream.map((line) => {
37
+ try {
38
+ const read = readLine(routes, places, JSON.parse(line));
39
+ answered.add(read.name);
40
+ return [read.name, read.outcome];
41
+ }
42
+ catch (error) {
43
+ broken = error instanceof Error ? error.message : String(error);
44
+ return null;
45
+ }
46
+ }), Stream.filter((entry) => entry !== null));
47
+ })).pipe(Stream.catchCause((cause) => {
48
+ const error = Cause.squash(cause);
49
+ broken =
50
+ error instanceof Error
51
+ ? error.message
52
+ : 'the Loader RPC did not answer';
53
+ return Stream.empty;
54
+ }),
55
+ // Every place the answer did not reach is broken, with why if it broke.
56
+ Stream.concat(Stream.suspend(() => Stream.fromIterable(wanted
57
+ .filter(({ name }) => !answered.has(name))
58
+ .map(({ name }) => [
59
+ name,
60
+ {
61
+ _tag: 'Broken',
62
+ reason: broken ?? `no answer for ${name}`,
63
+ },
64
+ ])))));
65
+ };
66
+ return Layer.succeed(Loading, {
67
+ each,
68
+ load: (wanted) => Stream.runCollect(each(wanted)).pipe(Effect.map((answers) => Object.fromEntries(answers))),
69
+ });
70
+ };
@@ -0,0 +1,66 @@
1
+ import type { ComponentType, ReactNode } from 'react';
2
+ import type { Layer } from 'effect';
3
+ import type { AnyActor, Needs } from '../../core/index.ts';
4
+ import type { ViewOf } from '../../react/index.ts';
5
+ import type { Navigation, PageBuild, PageDefinition } from '../../routing/index.ts';
6
+ import type { Codec, Metadata, Place, PlaceData, PlaceSchema } from '../../routing/route/index.ts';
7
+ /** What Start needs of the app the Router serves: what `Router.app(router, AppView)` gives. */
8
+ export interface ServedApp {
9
+ readonly actor: AnyActor;
10
+ readonly view: ViewOf<any>;
11
+ /** The Router's Input at a URL, with what its places start from, by dotted name. */
12
+ readonly startAt: (url?: string, known?: Readonly<Record<string, any>>) => {
13
+ readonly route: any;
14
+ readonly known?: object;
15
+ } | undefined;
16
+ readonly href: (route: any) => string;
17
+ /** The script that puts a page's scroll back before the app hydrates, or `null` where the Router restores none. */
18
+ readonly restoreScroll?: (route: any) => string | null;
19
+ readonly routes: {
20
+ readonly route: Codec<any>;
21
+ readonly path: (route: any) => string;
22
+ readonly metadata: (of: any, data?: PlaceData) => Metadata;
23
+ readonly places: (of: any) => ReadonlyArray<Place>;
24
+ readonly every: ReadonlyArray<PlaceSchema>;
25
+ };
26
+ }
27
+ export type DocumentType = ComponentType<{
28
+ readonly children: ReactNode;
29
+ }>;
30
+ declare const APP: unique symbol;
31
+ /** The app and what it needs in the browser: what `src/app` default-exports. */
32
+ export interface StartApp<A extends ServedApp = ServedApp> {
33
+ readonly [APP]: true;
34
+ readonly app: A;
35
+ /** The HTML around the app; the plainest one if none. */
36
+ readonly document?: DocumentType;
37
+ /** What the app's Actors Require in the browser, besides the address and the Loaders. */
38
+ readonly layer?: Layer.Layer<any, never, never>;
39
+ }
40
+ /** What the root page's build still needs from above, besides what the Router Provides. */
41
+ type NeedsOf<A> = Exclude<Needs<A>, Navigation>;
42
+ /** The app's Layer, which must cover every Capability the tree still needs. */
43
+ type AppOptions<A> = {
44
+ readonly document?: DocumentType;
45
+ } & ([NeedsOf<A>] extends [never] ? {
46
+ readonly layer?: Layer.Layer<never, never, never>;
47
+ } : {
48
+ readonly layer: Layer.Layer<NeedsOf<A>, never, never>;
49
+ });
50
+ /**
51
+ * The app, its Document, and what its Actors Require in the browser:
52
+ * `export default Start.app(router, AppView, { document, layer })`, where
53
+ * `AppView` draws the build of the router's root page. Leaving out a
54
+ * Capability the app Requires is a type error.
55
+ */
56
+ export declare const app: <G extends PageDefinition, A extends PageBuild<G>>(router: {
57
+ readonly root: G;
58
+ }, view: ViewOf<A>, ...[options]: [NeedsOf<A>] extends [never] ? [options?: AppOptions<A>] : [options: AppOptions<A>]) => StartApp;
59
+ /** Why a file's default export is refused: only Start's own values are checked by type. */
60
+ export declare const refused: (file: string, what: string) => Error;
61
+ /** Whether `value` is one of Start's own, by its brand. */
62
+ export declare const branded: (value: unknown, brand: symbol) => boolean;
63
+ /** What `src/app` default-exports: `Start.app(…)`, and nothing else, so its Layer is checked. */
64
+ export declare const appOf: (exported: unknown) => StartApp;
65
+ export {};
66
+ //# sourceMappingURL=app.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../../src/start/common/app.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { Router } from '../../routing/index.js';
2
+ const APP = Symbol.for('@kestack/kabuki/start/app');
3
+ /**
4
+ * The app, its Document, and what its Actors Require in the browser:
5
+ * `export default Start.app(router, AppView, { document, layer })`, where
6
+ * `AppView` draws the build of the router's root page. Leaving out a
7
+ * Capability the app Requires is a type error.
8
+ */
9
+ export const app = (router, view, ...[options]) => ({
10
+ [APP]: true,
11
+ app: Router.app(router, view),
12
+ ...options,
13
+ });
14
+ /** Why a file's default export is refused: only Start's own values are checked by type. */
15
+ export const refused = (file, what) => new Error(`[@kestack/kabuki/start] ${file} must default-export ${what}, so it is checked by type`);
16
+ /** Whether `value` is one of Start's own, by its brand. */
17
+ export const branded = (value, brand) => typeof value === 'object' && value !== null && brand in value;
18
+ /** What `src/app` default-exports: `Start.app(…)`, and nothing else, so its Layer is checked. */
19
+ export const appOf = (exported) => {
20
+ if (branded(exported, APP))
21
+ return exported;
22
+ throw refused('src/app', 'Start.app(router, AppView, { … })');
23
+ };
@@ -0,0 +1,26 @@
1
+ import { app } from './app.ts';
2
+ import { Document, Head, Scripts, useDrawn, useRuntime } from './document.tsx';
3
+ import type { DocumentProps as Props, Drawn as DrawnBy } from './document.tsx';
4
+ /**
5
+ * What an app writes for Start on both sides: `Start.app(…)`, the app with
6
+ * its Document and what it needs in the browser. The parts of the Document
7
+ * Start fills: `<Start.Head />` in its `<head>`, `<Start.Scripts />` at the
8
+ * end of its `<body>`; `Start.Document`, the plainest one;
9
+ * `Start.useDrawn()`, when and by which build the server drew the page; and
10
+ * `Start.useRuntime()`, the running app, for devtools in the Document.
11
+ */
12
+ export declare const Start: {
13
+ app: typeof app;
14
+ Document: typeof Document;
15
+ Head: typeof Head;
16
+ Scripts: typeof Scripts;
17
+ useDrawn: typeof useDrawn;
18
+ useRuntime: typeof useRuntime;
19
+ };
20
+ export declare namespace Start {
21
+ /** What the Document is drawn with: the app, as its children, to put in `<body>`. */
22
+ type DocumentProps = Props;
23
+ /** What `Start.useDrawn()` gives. */
24
+ type Drawn = DrawnBy;
25
+ }
26
+ //# sourceMappingURL=common.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../src/start/common/common.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC/E,OAAO,KAAK,EAAE,aAAa,IAAI,KAAK,EAAE,KAAK,IAAI,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAW/E;;;;;;;GAOG;AACH,eAAO,MAAM,KAAK;;;;;;;CAAyD,CAAC;AAE5E,MAAM,CAAC,OAAO,WAAW,KAAK,CAAC;IAC7B,qFAAqF;IACrF,KAAY,aAAa,GAAG,KAAK,CAAC;IAClC,qCAAqC;IACrC,KAAY,KAAK,GAAG,OAAO,CAAC;CAC7B"}
@@ -0,0 +1,19 @@
1
+ import { app } from './app.js';
2
+ import { Document, Head, Scripts, useDrawn, useRuntime } from './document.js';
3
+ /*
4
+ * Start, as `src/app` writes it, on both sides: what `@kestack/kabuki/start`
5
+ * gives. The server's own, `Start.layers()` for `src/loaders.server`, is
6
+ * `@kestack/kabuki/start/server`'s.
7
+ *
8
+ * src/app.tsx Start.app(router, AppView, { document, layer })
9
+ * src/document.tsx <Start.Head /> in its head, <Start.Scripts /> at the end of its body
10
+ */
11
+ /**
12
+ * What an app writes for Start on both sides: `Start.app(…)`, the app with
13
+ * its Document and what it needs in the browser. The parts of the Document
14
+ * Start fills: `<Start.Head />` in its `<head>`, `<Start.Scripts />` at the
15
+ * end of its `<body>`; `Start.Document`, the plainest one;
16
+ * `Start.useDrawn()`, when and by which build the server drew the page; and
17
+ * `Start.useRuntime()`, the running app, for devtools in the Document.
18
+ */
19
+ export const Start = { app, Document, Head, Scripts, useDrawn, useRuntime };
@@ -0,0 +1,44 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { AppRuntime } from '../../react/index.ts';
3
+ /**
4
+ * The Metadata, the styles and the preloads, in the order the browser wants
5
+ * them: the charset and viewport first, then the title and every Metadata
6
+ * tag, then the entry's styles and the chunks it imports. The Metadata is
7
+ * drawn on the server only: in the browser the Router writes it after every
8
+ * move, so React leaves the tags the server drew alone.
9
+ */
10
+ declare function Head(): import("react").JSX.Element;
11
+ /** The Page as JSON, which the browser starts from, and the client entry that does it. */
12
+ declare function Scripts(): import("react").JSX.Element;
13
+ /**
14
+ * When the server drew this page, and by which build; and whether the
15
+ * component that asks was in that drawing, `hydrated`, or was drawn later
16
+ * by the browser, after a move. `null` outside a page Start served, as in a
17
+ * test or a story. A component keeps its answer for as long as it is
18
+ * mounted.
19
+ */
20
+ declare function useDrawn(): Drawn | null;
21
+ /**
22
+ * The running app, for devtools drawn in the Document around it: its
23
+ * History, the Step shown, and how to show another. `null` on the server,
24
+ * which draws each request from a History of its own and runs none, and
25
+ * outside a page Start served.
26
+ */
27
+ declare function useRuntime(): AppRuntime | null;
28
+ /** The plainest Document, for an app that gives none: Start's parts in an English page. */
29
+ declare function Document({ children }: DocumentProps): import("react").JSX.Element;
30
+ /** What the Document is drawn with: the app, as its children, to put in `<body>`. */
31
+ export interface DocumentProps {
32
+ readonly children: ReactNode;
33
+ }
34
+ /** What `useDrawn()` gives: when and by which build the server drew the page, and whether the component asking was in it. */
35
+ export interface Drawn {
36
+ /** When the server drew the page, in milliseconds since the epoch, after its Loaders answered. */
37
+ readonly at: number;
38
+ /** The build that drew it; none in dev. */
39
+ readonly build: string | undefined;
40
+ /** Whether the component asking was drawn by the server and hydrated, rather than by the browser after. */
41
+ readonly hydrated: boolean;
42
+ }
43
+ export { Document, Head, Scripts, useDrawn, useRuntime };
44
+ //# sourceMappingURL=document.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"document.d.ts","sourceRoot":"","sources":["../../../src/start/common/document.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAWvD;;;;;;GAMG;AACH,iBAAS,IAAI,gCA6BZ;AAED,0FAA0F;AAC1F,iBAAS,OAAO,gCAgBf;AAID;;;;;;GAMG;AACH,iBAAS,QAAQ,IAAI,KAAK,GAAG,IAAI,CAWhC;AAED;;;;;GAKG;AACH,iBAAS,UAAU,IAAI,UAAU,GAAG,IAAI,CAGvC;AAED,2FAA2F;AAC3F,iBAAS,QAAQ,CAAC,EAAE,QAAQ,EAAE,EAAE,aAAa,+BAY5C;AAED,qFAAqF;AACrF,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;CAC9B;AAED,6HAA6H;AAC7H,MAAM,WAAW,KAAK;IACpB,kGAAkG;IAClG,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,2CAA2C;IAC3C,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,2GAA2G;IAC3G,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B;AAED,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC"}
@@ -0,0 +1,58 @@
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { use, useState, useSyncExternalStore } from 'react';
3
+ import { ID, PageContext, RuntimeContext, usePage } from './page.js';
4
+ /*
5
+ * The Document's two parts Start fills: `<Start.Head />` in its `<head>`,
6
+ * `<Start.Scripts />` at the end of its `<body>`. Each draws the Page of the
7
+ * request, which the server works out and the browser reads back, so the
8
+ * Document hydrates as it was drawn. Lazy Views' files are added to the head
9
+ * by the server once the page is drawn, after these.
10
+ */
11
+ /**
12
+ * The Metadata, the styles and the preloads, in the order the browser wants
13
+ * them: the charset and viewport first, then the title and every Metadata
14
+ * tag, then the entry's styles and the chunks it imports. The Metadata is
15
+ * drawn on the server only: in the browser the Router writes it after every
16
+ * move, so React leaves the tags the server drew alone.
17
+ */
18
+ function Head() {
19
+ const { page, metadata } = usePage('<Start.Head />');
20
+ return (_jsxs(_Fragment, { children: [_jsx("meta", { charSet: "utf-8" }), _jsx("meta", { name: "viewport", content: "width=device-width, initial-scale=1" }), metadata?.title !== undefined && _jsx("title", { children: metadata.title }), metadata?.tags.map(({ tag: Tag, attributes }, at) => (_jsx(Tag, { ...attributes }, at))), page.head.map((script, at) => script.src !== undefined ? (_jsx("script", { type: "module", src: script.src }, `h${at}`)) : (_jsx("script", { type: "module", dangerouslySetInnerHTML: { __html: script.code ?? '' } }, `h${at}`))), page.entry.styles.map((href) => (_jsx("link", { rel: "stylesheet", href: href }, href))), page.entry.preloads.map((href) => (_jsx("link", { rel: "modulepreload", href: href }, href)))] }));
21
+ }
22
+ /** The Page as JSON, which the browser starts from, and the client entry that does it. */
23
+ function Scripts() {
24
+ const { page, json } = usePage('<Start.Scripts />');
25
+ return (_jsxs(_Fragment, { children: [page.scroll && (_jsx("script", { dangerouslySetInnerHTML: { __html: page.scroll } })), _jsx("script", { type: "application/json", id: ID, dangerouslySetInnerHTML: { __html: json } }), _jsx("script", { type: "module", src: page.entry.script })] }));
26
+ }
27
+ const never = () => () => { };
28
+ /**
29
+ * When the server drew this page, and by which build; and whether the
30
+ * component that asks was in that drawing, `hydrated`, or was drawn later
31
+ * by the browser, after a move. `null` outside a page Start served, as in a
32
+ * test or a story. A component keeps its answer for as long as it is
33
+ * mounted.
34
+ */
35
+ function useDrawn() {
36
+ const drawn = use(PageContext);
37
+ // A server's snapshot is read on the server and while hydrating what it drew.
38
+ const hydrating = useSyncExternalStore(never, () => false, () => true);
39
+ const [hydrated] = useState(hydrating);
40
+ if (!drawn)
41
+ return null;
42
+ return { ...drawn.page.drawn, hydrated };
43
+ }
44
+ /**
45
+ * The running app, for devtools drawn in the Document around it: its
46
+ * History, the Step shown, and how to show another. `null` on the server,
47
+ * which draws each request from a History of its own and runs none, and
48
+ * outside a page Start served.
49
+ */
50
+ function useRuntime() {
51
+ const read = use(RuntimeContext);
52
+ return read ? read() : null;
53
+ }
54
+ /** The plainest Document, for an app that gives none: Start's parts in an English page. */
55
+ function Document({ children }) {
56
+ return (_jsxs("html", { lang: "en", children: [_jsx("head", { children: _jsx(Head, {}) }), _jsxs("body", { children: [children, _jsx(Scripts, {})] })] }));
57
+ }
58
+ export { Document, Head, Scripts, useDrawn, useRuntime };
@@ -0,0 +1,9 @@
1
+ export { Start } from './common.ts';
2
+ export { appOf, branded, refused } from './app.ts';
3
+ export type { DocumentType, ServedApp, StartApp } from './app.ts';
4
+ export { Document } from './document.tsx';
5
+ export { ID, PageContext, RuntimeContext, readPage, serialize, usePage, } from './page.ts';
6
+ export type { Assets, Build, Drawing, Drawn, Page, Script } from './page.ts';
7
+ export { NDJSON, PATH, loadable, readAsk, readLine, writeAsk, writeLine, } from './wire.ts';
8
+ export type { Line, RoutesOnWire, Wanted } from './wire.ts';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/start/common/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACnD,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EACL,EAAE,EACF,WAAW,EACX,cAAc,EACd,QAAQ,EACR,SAAS,EACT,OAAO,GACR,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAC7E,OAAO,EACL,MAAM,EACN,IAAI,EACJ,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,SAAS,GACV,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { Start } from './common.js';
2
+ export { appOf, branded, refused } from './app.js';
3
+ export { Document } from './document.js';
4
+ export { ID, PageContext, RuntimeContext, readPage, serialize, usePage, } from './page.js';
5
+ export { NDJSON, PATH, loadable, readAsk, readLine, writeAsk, writeLine, } from './wire.js';
@@ -0,0 +1,67 @@
1
+ import type { SavedHistory } from '../../core/index.ts';
2
+ import type { AppRuntime } from '../../react/index.ts';
3
+ import type { Tag } from '../../routing/route/index.ts';
4
+ /** A script Start writes in the head: Vite's client and React Refresh in dev. */
5
+ export interface Script {
6
+ readonly src?: string;
7
+ readonly code?: string;
8
+ }
9
+ /** The files one entry, or one lazy View, needs: its script, its styles and the chunks it imports. */
10
+ export interface Assets {
11
+ readonly script: string;
12
+ readonly styles: ReadonlyArray<string>;
13
+ readonly preloads: ReadonlyArray<string>;
14
+ }
15
+ /** What the Vite plugin gives the Worker about the build. */
16
+ export interface Build {
17
+ /** Changes on every build: the key the cache keeps static pages under. None in dev, where nothing is cached. */
18
+ readonly id: string | undefined;
19
+ /** Vite's `base`: where every file is served from. */
20
+ readonly base: string;
21
+ /** The client entry's files. */
22
+ readonly entry: Assets;
23
+ /** Each lazy View's files, by its id; `null` in dev, where a View's module is served at `base` and its id. */
24
+ readonly views: Readonly<Record<string, Assets>> | null;
25
+ /** Scripts the head needs before anything else: Vite's client and React Refresh in dev. */
26
+ readonly head: ReadonlyArray<Script>;
27
+ }
28
+ /** When the server drew a page, and which build drew it. */
29
+ export interface Drawing {
30
+ /** When it was drawn, in milliseconds since the epoch: after its Loaders answered. */
31
+ readonly at: number;
32
+ /** The build that drew it; none in dev. */
33
+ readonly build: string | undefined;
34
+ }
35
+ /** What the browser needs to draw the Document as the server did: its files, the History the app is drawn from, and when it was drawn. */
36
+ export interface Page {
37
+ readonly entry: Assets;
38
+ readonly head: ReadonlyArray<Script>;
39
+ readonly saved: SavedHistory;
40
+ readonly drawn: Drawing;
41
+ /** The script that puts the page's scroll back before the app hydrates, if the Router restores it here. */
42
+ readonly scroll?: string;
43
+ }
44
+ /**
45
+ * A Page and the JSON it is written as, the same text on the server and in
46
+ * the browser; on the server, the Metadata too. The browser leaves the
47
+ * Metadata the server drew to the Router, which writes it after every move.
48
+ */
49
+ export interface Drawn {
50
+ readonly page: Page;
51
+ readonly json: string;
52
+ readonly metadata?: {
53
+ readonly title: string | undefined;
54
+ readonly tags: ReadonlyArray<Tag>;
55
+ };
56
+ }
57
+ /** The id of the script that holds the Page as JSON. */
58
+ export declare const ID = "kabuki-start";
59
+ export declare const PageContext: import("react").Context<Drawn | undefined>;
60
+ /** How the Document reads the running app: the browser's App's `useRuntime`. A server has none. */
61
+ export declare const RuntimeContext: import("react").Context<(() => AppRuntime) | undefined>;
62
+ export declare const usePage: (what: string) => Drawn;
63
+ /** JSON safe inside a `<script>`: no `</script>`, no `<!--`, no line separators JavaScript reads as line ends. */
64
+ export declare const serialize: (page: Page) => Omit<Drawn, 'metadata'>;
65
+ /** The Page a server wrote in this document, read back as it was written. */
66
+ export declare const readPage: (document: Document) => Drawn;
67
+ //# sourceMappingURL=page.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../../src/start/common/page.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,8BAA8B,CAAC;AAUxD,iFAAiF;AACjF,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,sGAAsG;AACtG,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACvC,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CAC1C;AAED,6DAA6D;AAC7D,MAAM,WAAW,KAAK;IACpB,gHAAgH;IAChH,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,sDAAsD;IACtD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,gCAAgC;IAChC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,8GAA8G;IAC9G,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC;IACxD,2FAA2F;IAC3F,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CACtC;AAED,4DAA4D;AAC5D,MAAM,WAAW,OAAO;IACtB,sFAAsF;IACtF,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,2CAA2C;IAC3C,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;CACpC;AAED,0IAA0I;AAC1I,MAAM,WAAW,IAAI;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACrC,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,2GAA2G;IAC3G,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;GAIG;AACH,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,CAAC,EAAE;QAClB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;QACnC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC;KACnC,CAAC;CACH;AAED,wDAAwD;AACxD,eAAO,MAAM,EAAE,iBAAiB,CAAC;AAEjC,eAAO,MAAM,WAAW,4CAA8C,CAAC;AAEvE,mGAAmG;AACnG,eAAO,MAAM,cAAc,iCAAwB,UAAU,cAE5D,CAAC;AAEF,eAAO,MAAM,OAAO,SAAU,MAAM,KAAG,KAOtC,CAAC;AAEF,kHAAkH;AAClH,eAAO,MAAM,SAAS,SAAU,IAAI,KAAG,IAAI,CAAC,KAAK,EAAE,UAAU,CAQ3D,CAAC;AAEH,6EAA6E;AAC7E,eAAO,MAAM,QAAQ,aAAc,QAAQ,KAAG,KAO7C,CAAC"}
@@ -0,0 +1,29 @@
1
+ import { createContext, use } from 'react';
2
+ /** The id of the script that holds the Page as JSON. */
3
+ export const ID = 'kabuki-start';
4
+ export const PageContext = createContext(undefined);
5
+ /** How the Document reads the running app: the browser's App's `useRuntime`. A server has none. */
6
+ export const RuntimeContext = createContext(undefined);
7
+ export const usePage = (what) => {
8
+ const drawn = use(PageContext);
9
+ if (!drawn)
10
+ throw new Error(`[@kestack/kabuki/start] ${what} is drawn outside Start: only the Document Start serves can draw it`);
11
+ return drawn;
12
+ };
13
+ /** JSON safe inside a `<script>`: no `</script>`, no `<!--`, no line separators JavaScript reads as line ends. */
14
+ export const serialize = (page) => ({
15
+ page,
16
+ json: JSON.stringify(page)
17
+ .replace(/</g, '\\u003c')
18
+ .replace(/>/g, '\\u003e')
19
+ .replace(/&/g, '\\u0026')
20
+ .replace(/\u2028/g, '\\u2028')
21
+ .replace(/\u2029/g, '\\u2029'),
22
+ });
23
+ /** The Page a server wrote in this document, read back as it was written. */
24
+ export const readPage = (document) => {
25
+ const json = document.getElementById(ID)?.textContent;
26
+ if (!json)
27
+ throw new Error(`[@kestack/kabuki/start] this page holds no #${ID} script: was it drawn by Start, with <Start.Scripts /> in its Document?`);
28
+ return { page: JSON.parse(json), json };
29
+ };
@@ -0,0 +1,37 @@
1
+ import type { Codec, Outcome, PlaceSchema } from '../../routing/route/index.ts';
2
+ /** Where the server answers it. */
3
+ export declare const PATH = "/_kabuki/load";
4
+ /** What the wire needs of a Routes tree: every place, and the Schema of every Route. */
5
+ export interface RoutesOnWire {
6
+ readonly every: ReadonlyArray<PlaceSchema>;
7
+ readonly route: Codec<unknown>;
8
+ }
9
+ /** One line of the answer: what loading one place came to. */
10
+ export interface Line {
11
+ readonly name: string;
12
+ readonly outcome: Outcome;
13
+ }
14
+ /** The answer's media type: one JSON value per line. */
15
+ export declare const NDJSON = "application/x-ndjson";
16
+ /** A place to load, decoded: its dotted name and its params. */
17
+ export interface Wanted {
18
+ readonly name: string;
19
+ readonly params: Readonly<Record<string, unknown>>;
20
+ }
21
+ /** Every place with data, by dotted name: only those can be asked for. */
22
+ export declare const loadable: (routes: RoutesOnWire) => Map<string, PlaceSchema<string>>;
23
+ type Places = ReturnType<typeof loadable>;
24
+ export declare const writeAsk: (places: Places, wanted: ReadonlyArray<Wanted>) => {
25
+ places: {
26
+ name: string;
27
+ params: unknown;
28
+ }[];
29
+ };
30
+ /** The places a request asks for, or why it cannot be read. Throws on a malformed ask. */
31
+ export declare const readAsk: (places: Places, body: unknown) => ReadonlyArray<Wanted>;
32
+ /** One place's outcome as a line, its data and Redirect written with their Schemas. */
33
+ export declare const writeLine: (routes: RoutesOnWire, places: Places, line: Line) => Line;
34
+ /** A line read back with its Schemas. */
35
+ export declare const readLine: (routes: RoutesOnWire, places: Places, line: Line) => Line;
36
+ export {};
37
+ //# sourceMappingURL=wire.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wire.d.ts","sourceRoot":"","sources":["../../../src/start/common/wire.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAchF,mCAAmC;AACnC,eAAO,MAAM,IAAI,kBAAkB,CAAC;AAkBpC,wFAAwF;AACxF,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;IAC3C,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;CAChC;AAED,8DAA8D;AAC9D,MAAM,WAAW,IAAI;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAED,wDAAwD;AACxD,eAAO,MAAM,MAAM,yBAAyB,CAAC;AAE7C,gEAAgE;AAChE,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACpD;AAQD,0EAA0E;AAC1E,eAAO,MAAM,QAAQ,WAAY,YAAY,qCAK1C,CAAC;AAEJ,KAAK,MAAM,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAc1C,eAAO,MAAM,QAAQ,WAAY,MAAM,UAAU,aAAa,CAAC,MAAM,CAAC;IACpE,MAAM;;;;CAON,CAAC;AAEH,0FAA0F;AAC1F,eAAO,MAAM,OAAO,WAAY,MAAM,QAAQ,OAAO,KAAG,aAAa,CAAC,MAAM,CAUvE,CAAC;AAiDN,uFAAuF;AACvF,eAAO,MAAM,SAAS,WA9CX,YAAY,UAAU,MAAM,QAAQ,IAAI,KAAG,IA8CR,CAAC;AAC/C,yCAAyC;AACzC,eAAO,MAAM,QAAQ,WAhDV,YAAY,UAAU,MAAM,QAAQ,IAAI,KAAG,IAgDT,CAAC"}
@@ -0,0 +1,73 @@
1
+ import { Exit, Schema } from 'effect';
2
+ /*
3
+ * The Loader RPC: how the browser asks the server for the data of the
4
+ * places a move needs, all in one request. Made from the Routes, so it
5
+ * cannot disagree with them: a place with data is one call, what its Loader
6
+ * is handed the payload, and its outcome the answer.
7
+ *
8
+ * It is a fixed JSON protocol over the Routes' Schemas rather than an
9
+ * `effect/rpc` group: a move asks for all its places at once, which one
10
+ * request with one answer says directly, a Loader is handed the very request
11
+ * that asked, cookies and all, and the browser ships no RPC client.
12
+ */
13
+ /** Where the server answers it. */
14
+ export const PATH = '/_kabuki/load';
15
+ /** The answer's media type: one JSON value per line. */
16
+ export const NDJSON = 'application/x-ndjson';
17
+ const Ask = Schema.Struct({
18
+ places: Schema.Array(Schema.Struct({ name: Schema.String, params: Schema.Unknown })),
19
+ });
20
+ /** Every place with data, by dotted name: only those can be asked for. */
21
+ export const loadable = (routes) => new Map(routes.every.flatMap((place) => place.input ? [[place.name, place]] : []));
22
+ const placeOf = (places, name) => {
23
+ const place = places.get(name);
24
+ if (!place)
25
+ throw new Error(`[@kestack/kabuki/start] ${name} is not a place with data`);
26
+ return place;
27
+ };
28
+ const sync = (exit, what) => {
29
+ if (Exit.isSuccess(exit))
30
+ return exit.value;
31
+ throw new Error(`[@kestack/kabuki/start] ${what}`, { cause: exit.cause });
32
+ };
33
+ export const writeAsk = (places, wanted) => ({
34
+ places: wanted.map(({ name, params }) => ({
35
+ name,
36
+ params: sync(Schema.encodeUnknownExit(placeOf(places, name).params)(params), `the params of ${name} do not match its Schema`),
37
+ })),
38
+ });
39
+ /** The places a request asks for, or why it cannot be read. Throws on a malformed ask. */
40
+ export const readAsk = (places, body) => sync(Schema.decodeUnknownExit(Ask)(body), 'the ask is not { places: [{ name, params }] }').places.map(({ name, params }) => ({
41
+ name,
42
+ params: sync(Schema.decodeUnknownExit(placeOf(places, name).params)(params), `the params of ${name} do not match its Schema`),
43
+ }));
44
+ const outcomeWith = (direction) => (routes, places, line) => {
45
+ const { name } = line;
46
+ // Only the outcome goes on the wire: what a Loading adds besides, as
47
+ // how long it took, the browser works out for itself.
48
+ const { took: _took, at: _at, cached: _cached, stale: _stale, ...outcome } = line.outcome;
49
+ const code = (schema) => (value) => direction === 'encode'
50
+ ? Schema.encodeUnknownExit(schema)(value)
51
+ : Schema.decodeUnknownExit(schema)(value);
52
+ if (outcome._tag === 'Loaded')
53
+ return {
54
+ name,
55
+ outcome: {
56
+ _tag: 'Loaded',
57
+ data: sync(code(placeOf(places, name).input)(outcome.data), `the data of ${name} does not match its Schema`),
58
+ },
59
+ };
60
+ if (outcome._tag === 'Redirect' && outcome.href === undefined)
61
+ return {
62
+ name,
63
+ outcome: {
64
+ ...outcome,
65
+ route: sync(code(routes.route)(outcome.route), 'a Redirect names no Route'),
66
+ },
67
+ };
68
+ return { name, outcome: outcome };
69
+ };
70
+ /** One place's outcome as a line, its data and Redirect written with their Schemas. */
71
+ export const writeLine = outcomeWith('encode');
72
+ /** A line read back with its Schemas. */
73
+ export const readLine = outcomeWith('decode');
@@ -0,0 +1,8 @@
1
+ import type { Handler, Platform } from '../index.ts';
2
+ /** Cloudflare Workers, for `start({ platform: cloudflare() })`. */
3
+ export declare const cloudflare: () => Platform;
4
+ /** Start's handler as a Worker's: what the Worker's main default-exports. */
5
+ export declare const serve: (handler: Handler) => {
6
+ fetch: (request: Request, env: unknown) => Promise<Response>;
7
+ };
8
+ //# sourceMappingURL=cloudflare.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloudflare.d.ts","sourceRoot":"","sources":["../../../../src/start/platform/cloudflare/cloudflare.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAa,QAAQ,EAAE,MAAM,aAAa,CAAC;AAUhE,mEAAmE;AACnE,eAAO,MAAM,UAAU,QAAO,QAY5B,CAAC;AAOH,6EAA6E;AAC7E,eAAO,MAAM,KAAK,YAAa,OAAO;IACpC,KAAK,YAAY,OAAO,OAAO,OAAO,KAAG,OAAO,CAAC,QAAQ,CAAC;CAI1D,CAAC"}
@@ -0,0 +1,31 @@
1
+ /*
2
+ * Start on Cloudflare Workers. `cloudflare()` is what the Vite plugin
3
+ * builds for: one module, its dependencies in their edge form, which
4
+ * Alchemy's `Cloudflare.Website.Vite` deploys in front of the client's
5
+ * assets. `serve(handler)` is the Worker: each request handed to Start with
6
+ * the Worker's env and the Cloudflare Cache.
7
+ */
8
+ /** Cloudflare Workers, for `start({ platform: cloudflare() })`. */
9
+ export const cloudflare = () => ({
10
+ name: 'cloudflare',
11
+ conditions: [
12
+ 'workerd',
13
+ 'worker',
14
+ 'edge-light',
15
+ 'module',
16
+ 'browser',
17
+ 'import',
18
+ 'default',
19
+ ],
20
+ serve: { from: '@kestack/kabuki/start/platform/cloudflare', name: 'serve' },
21
+ });
22
+ /** The Cloudflare Cache of this data center; none outside workerd, as in Node. */
23
+ const theCache = () => globalThis.caches
24
+ ?.default;
25
+ /** Start's handler as a Worker's: what the Worker's main default-exports. */
26
+ export const serve = (handler) => ({
27
+ fetch: (request, env) => {
28
+ const cache = theCache();
29
+ return handler.fetch(request, cache ? { env, cache } : { env });
30
+ },
31
+ });