zitejs 0.10.0-start.4 → 0.10.0-start.5
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.
- package/dist/cjs/start/entries.d.ts +6 -2
- package/dist/cjs/start/entries.js +13 -2
- package/dist/esm/start/entries.d.ts +6 -2
- package/dist/esm/start/entries.js +13 -2
- package/dist/esm/start/server.d.ts +24 -10
- package/dist/esm/start/server.js +41 -8
- package/dist/esm/start/types.d.ts +11 -2
- package/dist/esm/start/vite.js +4 -3
- package/dist/esm/start/worker.d.ts +11 -0
- package/dist/esm/start/worker.js +20 -0
- package/package.json +6 -1
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import type { SourceDir } from "../sourceRoots.js";
|
|
2
2
|
export declare const START_SERVER_ENTRY = ".zite/server.ts";
|
|
3
3
|
export declare const START_INSTANCE_ENTRY = ".zite/start.ts";
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
export type StartTarget = "cloudflare" | "node";
|
|
5
|
+
/**
|
|
6
|
+
* The server entry every Start app builds with. Platform-owned: regenerated,
|
|
7
|
+
* never edited. On Workers it's an entrypoint the host can also call over RPC.
|
|
8
|
+
*/
|
|
9
|
+
export declare const renderStartServerEntry: (target?: StartTarget) => string;
|
|
6
10
|
/** The start instance: the platform's middleware, then the app's own `src/start.ts` when it has one. */
|
|
7
11
|
export declare const renderStartInstance: (hasAppStart: boolean) => string;
|
|
8
12
|
export declare const hasAppStart: (appDir: string) => boolean;
|
|
@@ -8,8 +8,19 @@ const node_path_1 = require("node:path");
|
|
|
8
8
|
exports.START_SERVER_ENTRY = ".zite/server.ts";
|
|
9
9
|
exports.START_INSTANCE_ENTRY = ".zite/start.ts";
|
|
10
10
|
const APP_START_FILES = ["src/start.ts", "src/start.tsx"];
|
|
11
|
-
/**
|
|
12
|
-
|
|
11
|
+
/**
|
|
12
|
+
* The server entry every Start app builds with. Platform-owned: regenerated,
|
|
13
|
+
* never edited. On Workers it's an entrypoint the host can also call over RPC.
|
|
14
|
+
*/
|
|
15
|
+
const renderStartServerEntry = (target = "cloudflare") => target === "cloudflare"
|
|
16
|
+
? `// Generated by zitejs for TanStack Start apps. The platform owns this file.
|
|
17
|
+
import handler from '@tanstack/react-start/server-entry';
|
|
18
|
+
import { createZiteWorker } from 'zitejs/start/worker';
|
|
19
|
+
import { getRouter } from '../src/router';
|
|
20
|
+
|
|
21
|
+
export default createZiteWorker({ handler, getRouter });
|
|
22
|
+
`
|
|
23
|
+
: `// Generated by zitejs for TanStack Start apps. The platform owns this file.
|
|
13
24
|
import handler, { createServerEntry } from '@tanstack/react-start/server-entry';
|
|
14
25
|
import { createZiteFetch } from 'zitejs/start/server';
|
|
15
26
|
import { getRouter } from '../src/router';
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import type { SourceDir } from "../sourceRoots.js";
|
|
2
2
|
export declare const START_SERVER_ENTRY = ".zite/server.ts";
|
|
3
3
|
export declare const START_INSTANCE_ENTRY = ".zite/start.ts";
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
export type StartTarget = "cloudflare" | "node";
|
|
5
|
+
/**
|
|
6
|
+
* The server entry every Start app builds with. Platform-owned: regenerated,
|
|
7
|
+
* never edited. On Workers it's an entrypoint the host can also call over RPC.
|
|
8
|
+
*/
|
|
9
|
+
export declare const renderStartServerEntry: (target?: StartTarget) => string;
|
|
6
10
|
/** The start instance: the platform's middleware, then the app's own `src/start.ts` when it has one. */
|
|
7
11
|
export declare const renderStartInstance: (hasAppStart: boolean) => string;
|
|
8
12
|
export declare const hasAppStart: (appDir: string) => boolean;
|
|
@@ -3,8 +3,19 @@ import { dirname, join, relative } from "node:path";
|
|
|
3
3
|
export const START_SERVER_ENTRY = ".zite/server.ts";
|
|
4
4
|
export const START_INSTANCE_ENTRY = ".zite/start.ts";
|
|
5
5
|
const APP_START_FILES = ["src/start.ts", "src/start.tsx"];
|
|
6
|
-
/**
|
|
7
|
-
|
|
6
|
+
/**
|
|
7
|
+
* The server entry every Start app builds with. Platform-owned: regenerated,
|
|
8
|
+
* never edited. On Workers it's an entrypoint the host can also call over RPC.
|
|
9
|
+
*/
|
|
10
|
+
export const renderStartServerEntry = (target = "cloudflare") => target === "cloudflare"
|
|
11
|
+
? `// Generated by zitejs for TanStack Start apps. The platform owns this file.
|
|
12
|
+
import handler from '@tanstack/react-start/server-entry';
|
|
13
|
+
import { createZiteWorker } from 'zitejs/start/worker';
|
|
14
|
+
import { getRouter } from '../src/router';
|
|
15
|
+
|
|
16
|
+
export default createZiteWorker({ handler, getRouter });
|
|
17
|
+
`
|
|
18
|
+
: `// Generated by zitejs for TanStack Start apps. The platform owns this file.
|
|
8
19
|
import handler, { createServerEntry } from '@tanstack/react-start/server-entry';
|
|
9
20
|
import { createZiteFetch } from 'zitejs/start/server';
|
|
10
21
|
import { getRouter } from '../src/router';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { HostProps, PlatformBinding, ZiteRequestContext } from "./types.js";
|
|
1
|
+
import type { HostProps, PlatformBinding, RenderWatch, ZiteRequestContext } from "./types.js";
|
|
2
2
|
export { runWithHost } from "./scope.js";
|
|
3
3
|
export { describeApp } from "./describe.js";
|
|
4
|
-
export type { HostProps, PlatformBinding, PlatformCallInput, PlatformCallResult, PlatformSession, RunRecord } from "./types.js";
|
|
4
|
+
export type { HostProps, PlatformBinding, PlatformCallInput, PlatformCallResult, PlatformSession, RenderWatch, RunRecord } from "./types.js";
|
|
5
5
|
/**
|
|
6
6
|
* Routes every zitejs data, integration and email call to this request's
|
|
7
7
|
* platform, on one session, and only inside an access scope. The access kind
|
|
@@ -22,16 +22,30 @@ export declare const builtFunctionIds: () => string[];
|
|
|
22
22
|
/** Each server function's `description` option, written in by `zite()` at build. */
|
|
23
23
|
export declare const builtFunctionDescriptions: () => Record<string, string>;
|
|
24
24
|
type Fetch = (request: Request, ...rest: unknown[]) => Promise<Response> | Response;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
* if one is given.
|
|
30
|
-
*/
|
|
31
|
-
export declare function createZiteFetch(options: {
|
|
25
|
+
type WorkerContext = {
|
|
26
|
+
waitUntil(promise: Promise<unknown>): void;
|
|
27
|
+
};
|
|
28
|
+
export type ZiteServerOptions = {
|
|
32
29
|
handler: {
|
|
33
30
|
fetch: Fetch;
|
|
34
31
|
};
|
|
35
32
|
getRouter: () => unknown;
|
|
36
33
|
platform?: PlatformBinding;
|
|
37
|
-
}
|
|
34
|
+
};
|
|
35
|
+
type HostedContext = WorkerContext & {
|
|
36
|
+
props?: Partial<HostProps>;
|
|
37
|
+
};
|
|
38
|
+
export type ZiteHandlers = {
|
|
39
|
+
fetch: Fetch;
|
|
40
|
+
/** A page the host may cache: as `fetch`, with every read and outbound fetch reported to `watch`. */
|
|
41
|
+
render(request: Request, ctx: HostedContext, watch: RenderWatch): Promise<Response>;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* The handlers of a Start app's server entry. A request the host dispatched
|
|
45
|
+
* carries its identity and platform in props; anything else (describe under
|
|
46
|
+
* `vite preview`, tests) reads `x-zite-*` headers and uses `platform` if one
|
|
47
|
+
* is given.
|
|
48
|
+
*/
|
|
49
|
+
export declare function createZiteHandlers(options: ZiteServerOptions): ZiteHandlers;
|
|
50
|
+
/** The fetch handler alone, for entries that take no RPC. */
|
|
51
|
+
export declare function createZiteFetch(options: ZiteServerOptions): Fetch;
|
package/dist/esm/start/server.js
CHANGED
|
@@ -18,7 +18,7 @@ export function installPlatformTransport() {
|
|
|
18
18
|
// Fails closed: no platform means no platform access, never a fallback.
|
|
19
19
|
if (!host?.platform)
|
|
20
20
|
throw new Error("The Zite platform binding is missing");
|
|
21
|
-
host.session ??= Promise.resolve(host.platform.session());
|
|
21
|
+
host.session ??= Promise.resolve(host.watch ? host.platform.session(host.watch) : host.platform.session());
|
|
22
22
|
const result = await (await host.session).call({ integrationId, className, methodName, params, access: scope.kind });
|
|
23
23
|
if ("value" in result)
|
|
24
24
|
return result.value;
|
|
@@ -26,7 +26,31 @@ export function installPlatformTransport() {
|
|
|
26
26
|
throw new ZiteError(code in ZITE_ERROR_STATUS ? code : "INTERNAL_ERROR", message);
|
|
27
27
|
};
|
|
28
28
|
globalThis.__wrapSdkCall = sdkCall;
|
|
29
|
+
watchOutboundFetches();
|
|
29
30
|
}
|
|
31
|
+
let fetchesWatched = false;
|
|
32
|
+
const fetchedHost = (input) => {
|
|
33
|
+
try {
|
|
34
|
+
return new URL(input instanceof Request ? input.url : input).host;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return "?";
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
// A page that fetched depends on more than the reads the host saw, so the host
|
|
41
|
+
// must hear of it before the fetch goes out. Next patches fetch for the same reason.
|
|
42
|
+
const watchOutboundFetches = () => {
|
|
43
|
+
if (fetchesWatched)
|
|
44
|
+
return;
|
|
45
|
+
fetchesWatched = true;
|
|
46
|
+
const nativeFetch = globalThis.fetch.bind(globalThis);
|
|
47
|
+
globalThis.fetch = async (input, init) => {
|
|
48
|
+
const watch = getHost()?.watch;
|
|
49
|
+
if (watch)
|
|
50
|
+
await watch.uncacheable(`fetch ${fetchedHost(input)}`);
|
|
51
|
+
return nativeFetch(input, init);
|
|
52
|
+
};
|
|
53
|
+
};
|
|
30
54
|
const decodeUser = (value) => JSON.parse(new TextDecoder().decode(Uint8Array.from(atob(value.replace(/-/g, "+").replace(/_/g, "/")), (c) => c.charCodeAt(0))));
|
|
31
55
|
const INVOKE_KINDS = new Set(["webhook", "describe", "workflow", "warm"]);
|
|
32
56
|
/** What the host dispatched this request with. Headers are ignored: props are the only thing it alone can set. */
|
|
@@ -114,21 +138,22 @@ const pageStatus = (host) => {
|
|
|
114
138
|
return isZiteError(failed) ? ZITE_ERROR_STATUS[failed.code] : undefined;
|
|
115
139
|
};
|
|
116
140
|
/**
|
|
117
|
-
* The
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
*
|
|
141
|
+
* The handlers of a Start app's server entry. A request the host dispatched
|
|
142
|
+
* carries its identity and platform in props; anything else (describe under
|
|
143
|
+
* `vite preview`, tests) reads `x-zite-*` headers and uses `platform` if one
|
|
144
|
+
* is given.
|
|
121
145
|
*/
|
|
122
|
-
export function
|
|
146
|
+
export function createZiteHandlers(options) {
|
|
123
147
|
installPlatformTransport();
|
|
124
148
|
// Loaded on first use, so a page request never pays for importing workflow modules.
|
|
125
149
|
let workflows;
|
|
126
150
|
const loadedWorkflows = () => (workflows ??= loadWorkflows());
|
|
127
|
-
|
|
128
|
-
const ctx = rest[1];
|
|
151
|
+
const serve = async (request, ctx, watch) => {
|
|
129
152
|
const host = ctx?.props?.platform
|
|
130
153
|
? hostContextFromProps(request, ctx.props)
|
|
131
154
|
: hostContextFromRequest(request, options.platform);
|
|
155
|
+
if (watch)
|
|
156
|
+
host.watch = watch;
|
|
132
157
|
// Starting this isolate was the point: the platform warms a build before its
|
|
133
158
|
// first visitors, and no app code runs.
|
|
134
159
|
if (host.invoke?.kind === "warm")
|
|
@@ -161,4 +186,12 @@ export function createZiteFetch(options) {
|
|
|
161
186
|
ctx?.waitUntil(flushed);
|
|
162
187
|
});
|
|
163
188
|
};
|
|
189
|
+
return {
|
|
190
|
+
fetch: (request, ...rest) => serve(request, rest[1]),
|
|
191
|
+
render: (request, ctx, watch) => serve(request, ctx, watch),
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
/** The fetch handler alone, for entries that take no RPC. */
|
|
195
|
+
export function createZiteFetch(options) {
|
|
196
|
+
return createZiteHandlers(options).fetch;
|
|
164
197
|
}
|
|
@@ -47,10 +47,17 @@ export type PlatformSession = {
|
|
|
47
47
|
runs: RunRecord[];
|
|
48
48
|
}): Promise<void>;
|
|
49
49
|
};
|
|
50
|
+
/**
|
|
51
|
+
* The host's ear on a page render it may cache, from `render()`. Reports can
|
|
52
|
+
* only make the page less cacheable, so an app gains nothing by sending them.
|
|
53
|
+
*/
|
|
54
|
+
export type RenderWatch = {
|
|
55
|
+
uncacheable(reason: string): Promise<void>;
|
|
56
|
+
};
|
|
50
57
|
/** What the host hands each request: its platform, already scoped to the app, build, request and user. */
|
|
51
58
|
export type PlatformBinding = {
|
|
52
|
-
/** Every platform call of one request goes through one session. */
|
|
53
|
-
session(): PlatformSession | Promise<PlatformSession>;
|
|
59
|
+
/** Every platform call of one request goes through one session. A render's session reports what it read to `watch`. */
|
|
60
|
+
session(watch?: RenderWatch): PlatformSession | Promise<PlatformSession>;
|
|
54
61
|
/** One batch per request, after its response has ended. */
|
|
55
62
|
runs(batch: {
|
|
56
63
|
runs: RunRecord[];
|
|
@@ -80,6 +87,8 @@ export type ZiteRequestContext = {
|
|
|
80
87
|
runs: RunRecord[];
|
|
81
88
|
platform?: PlatformBinding;
|
|
82
89
|
session?: Promise<PlatformSession>;
|
|
90
|
+
/** Set when the host renders a page it may cache. */
|
|
91
|
+
watch?: RenderWatch;
|
|
83
92
|
/** This request's router, so a page's status can follow the error it rendered. */
|
|
84
93
|
router?: unknown;
|
|
85
94
|
};
|
package/dist/esm/start/vite.js
CHANGED
|
@@ -32,8 +32,9 @@ export function zite(options = {}) {
|
|
|
32
32
|
// Platform-owned, so they're rewritten whenever they differ. Sandboxes run the
|
|
33
33
|
// image's zitejs for `generate`, which may predate Start; the plugin can't.
|
|
34
34
|
const appDir = process.cwd();
|
|
35
|
-
if (!options.serverEntry)
|
|
36
|
-
writeIfChanged(appDir, START_SERVER_ENTRY, renderStartServerEntry());
|
|
35
|
+
if (!options.serverEntry) {
|
|
36
|
+
writeIfChanged(appDir, START_SERVER_ENTRY, renderStartServerEntry(options.cloudflare === false ? "node" : "cloudflare"));
|
|
37
|
+
}
|
|
37
38
|
writeIfChanged(appDir, START_INSTANCE_ENTRY, renderStartInstance(hasAppStart(appDir)));
|
|
38
39
|
// Every server function TanStack's compiler found, from its own hook, by id.
|
|
39
40
|
const ids = new Map();
|
|
@@ -125,7 +126,7 @@ export function zite(options = {}) {
|
|
|
125
126
|
behavior: "error",
|
|
126
127
|
client: {
|
|
127
128
|
// Appended to TanStack's own.
|
|
128
|
-
specifiers: ["zitejs/start/server", "zitejs/start/describe", "zitejs/runtime"],
|
|
129
|
+
specifiers: ["zitejs/start/server", "zitejs/start/worker", "zitejs/start/describe", "zitejs/runtime"],
|
|
129
130
|
// Replaces TanStack's list, so its `**/*.server.*` is restated. File
|
|
130
131
|
// patterns also catch `zitejs/db` and `zitejs/integrations`, which the
|
|
131
132
|
// aliases above rewrite before specifiers are matched.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type ZiteServerOptions } from "./server.js";
|
|
2
|
+
import type { RenderWatch } from "./types.js";
|
|
3
|
+
export type ZiteWorker = new (ctx: unknown, env: unknown) => {
|
|
4
|
+
fetch(request: Request): Promise<Response>;
|
|
5
|
+
render(request: Request, watch: RenderWatch): Promise<Response>;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* A Start app's Worker. The host sends most requests to `fetch`, and a page it
|
|
9
|
+
* may cache to `render` over RPC, with a watch for what the page depends on.
|
|
10
|
+
*/
|
|
11
|
+
export declare function createZiteWorker(options: ZiteServerOptions): ZiteWorker;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// For the generated server entry of a Workers build only. Apps never import this.
|
|
2
|
+
import { WorkerEntrypoint } from "cloudflare:workers";
|
|
3
|
+
import { createZiteHandlers } from "./server.js";
|
|
4
|
+
/**
|
|
5
|
+
* A Start app's Worker. The host sends most requests to `fetch`, and a page it
|
|
6
|
+
* may cache to `render` over RPC, with a watch for what the page depends on.
|
|
7
|
+
*/
|
|
8
|
+
export function createZiteWorker(options) {
|
|
9
|
+
const handlers = createZiteHandlers(options);
|
|
10
|
+
return class extends WorkerEntrypoint {
|
|
11
|
+
async fetch(request) {
|
|
12
|
+
return handlers.fetch(request, this.env, this.ctx);
|
|
13
|
+
}
|
|
14
|
+
// An argument's stubs are disposed when the call returns, and a streamed
|
|
15
|
+
// page can still read after that.
|
|
16
|
+
async render(request, watch) {
|
|
17
|
+
return handlers.render(request, this.ctx, watch.dup?.() ?? watch);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zitejs",
|
|
3
|
-
"version": "0.10.0-start.
|
|
3
|
+
"version": "0.10.0-start.5",
|
|
4
4
|
"description": "The Zite framework — build apps on Zite Database",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -101,6 +101,11 @@
|
|
|
101
101
|
"import": "./dist/esm/start/server.js",
|
|
102
102
|
"default": "./dist/esm/start/server.js"
|
|
103
103
|
},
|
|
104
|
+
"./start/worker": {
|
|
105
|
+
"types": "./dist/esm/start/worker.d.ts",
|
|
106
|
+
"import": "./dist/esm/start/worker.js",
|
|
107
|
+
"default": "./dist/esm/start/worker.js"
|
|
108
|
+
},
|
|
104
109
|
"./start/instance": {
|
|
105
110
|
"types": "./dist/esm/start/instance.d.ts",
|
|
106
111
|
"import": "./dist/esm/start/instance.js",
|