@junejs/server 1.0.0-dev.29 → 1.0.0-dev.36
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/agent-compile.d.ts +8 -9
- package/dist/agent-discover.d.ts +3 -4
- package/dist/agent-durable.d.ts +20 -19
- package/dist/agent-durable.js +41 -6
- package/dist/agent-native.d.ts +10 -11
- package/dist/agent-native.js +6 -2
- package/dist/app.d.ts +4 -5
- package/dist/app.js +2 -1
- package/dist/blob.d.ts +4 -5
- package/dist/build.d.ts +6 -6
- package/dist/build.js +34 -7
- package/dist/client-bundle.d.ts +8 -9
- package/dist/{config-freeze-DwI-Rmvq.d.ts → config-freeze-ZWC_Qd4h.d.ts} +1 -1
- package/dist/config-freeze.d.ts +1 -1
- package/dist/config-loader.d.ts +3 -4
- package/dist/connection-auth.d.ts +8 -9
- package/dist/content.d.ts +9 -10
- package/dist/core-version.d.ts +3 -4
- package/dist/css-modules-ambient.d.ts +2 -1
- package/dist/css-modules.d.ts +10 -11
- package/dist/css.d.ts +9 -10
- package/dist/d1-migrate.d.ts +6 -7
- package/dist/d1-migrate.js +3 -2
- package/dist/db.d.ts +2 -2
- package/dist/deploy.d.ts +3 -4
- package/dist/deploy.js +3 -2
- package/dist/dev-reload.d.ts +3 -4
- package/dist/dev.d.ts +4 -5
- package/dist/favicon.d.ts +16 -17
- package/dist/host.d.ts +5 -5
- package/dist/icon-letter.d.ts +2 -3
- package/dist/index.d.ts +4 -4
- package/dist/instrumentation.d.ts +2 -3
- package/dist/instrumentation.js +2 -1
- package/dist/island-registry.d.ts +6 -7
- package/dist/isolate-local.d.ts +4 -5
- package/dist/kv.d.ts +3 -4
- package/dist/llms-links.d.ts +8 -5
- package/dist/llms-links.js +31 -1
- package/dist/{manifest-gcNWqWoI.d.ts → manifest-DSNX4I-G.d.ts} +2 -2
- package/dist/manifest.d.ts +1 -1
- package/dist/negotiate.d.ts +4 -3
- package/dist/negotiate.js +24 -14
- package/dist/{pipeline-cCR6MGNK.d.ts → pipeline-BHUjBO0G.d.ts} +5 -1
- package/dist/pipeline.d.ts +2 -2
- package/dist/pipeline.js +260 -41
- package/dist/resources.d.ts +5 -6
- package/dist/router.d.ts +12 -13
- package/dist/rsc-build.d.ts +6 -7
- package/dist/rsc-bundle.d.ts +6 -7
- package/dist/rsc-manifest.d.ts +5 -6
- package/dist/rsc-runtime/flight-render-routes.d.ts +3 -4
- package/dist/rsc-runtime/flight-render.d.ts +2 -3
- package/dist/rsc-runtime/flight-to-html.d.ts +2 -3
- package/dist/rsc-runtime/flight-to-html.js +3 -2
- package/dist/rsc-runtime/rsdw-shims.d.ts +2 -1
- package/dist/segment.d.ts +4 -5
- package/dist/sqlite-driver.d.ts +10 -11
- package/dist/static-files.d.ts +4 -5
- package/dist/tsconfig-jsx.d.ts +4 -5
- package/dist/turn-events.d.ts +2 -3
- package/dist/web-manifest.d.ts +3 -4
- package/dist/web-manifest.js +2 -6
- package/dist/{worker-BkFHGtxp.d.ts → worker-Dv4l6Ybs.d.ts} +4 -2
- package/dist/worker.d.ts +1 -1
- package/dist/worker.js +35 -18
- package/package.json +5 -5
- package/src/agent-durable.ts +39 -10
- package/src/agent-native.ts +5 -1
- package/src/build.ts +63 -5
- package/src/llms-links.ts +46 -1
- package/src/negotiate.ts +39 -15
- package/src/pipeline.ts +433 -45
- package/src/web-manifest.ts +2 -6
- package/src/worker.ts +55 -17
package/src/web-manifest.ts
CHANGED
|
@@ -2,17 +2,13 @@
|
|
|
2
2
|
// Home Screen" name, icons, and colours, built from the same config the
|
|
3
3
|
// document renders with. Worker-safe (no node:*): the pipeline serves it like
|
|
4
4
|
// the SVG favicon, so dev, the worker, and the static build all agree.
|
|
5
|
+
import { siteShortName } from "@junejs/core/config";
|
|
5
6
|
import { resolveThemeColor, type DocumentConfig } from "@junejs/core/document";
|
|
6
7
|
|
|
7
8
|
// The home-screen label: site.shortName, else the site name's leading segment
|
|
8
9
|
// ("June — build agents into real apps" → "June"). Launchers truncate past
|
|
9
10
|
// ~12 characters, and a tagline is never the label anyone wants.
|
|
10
|
-
export
|
|
11
|
-
if (site.shortName) return site.shortName;
|
|
12
|
-
const name = site.name?.trim();
|
|
13
|
-
if (!name) return undefined;
|
|
14
|
-
return name.split(/\s+[—–|-]\s+|:\s+/)[0]!.trim() || name;
|
|
15
|
-
}
|
|
11
|
+
export const shortName = (site: DocumentConfig["site"]): string | undefined => siteShortName(site);
|
|
16
12
|
|
|
17
13
|
export function webManifest(config: DocumentConfig): string {
|
|
18
14
|
const base = config.basePath ?? "";
|
package/src/worker.ts
CHANGED
|
@@ -21,6 +21,7 @@ import type { Channel, ChannelFactory } from "@junejs/core/agent-config";
|
|
|
21
21
|
|
|
22
22
|
import { createPipeline, type ExtraHandler, type LayoutComponent, type LoadingComponent, type Resolved, type ResolvedResource, type ResourceHandler } from "./pipeline";
|
|
23
23
|
import { durableAgentSurface, durableChannelSurface, type DurableObjectNamespace } from "./agent-durable";
|
|
24
|
+
import { acceptTarget } from "./negotiate";
|
|
24
25
|
import { contentTypeFor, RESERVED_PREFIX, safeRelativePath } from "./static-files";
|
|
25
26
|
|
|
26
27
|
// The slice of workerd's ExecutionContext the worker threads through: webhook
|
|
@@ -125,8 +126,11 @@ function compilePattern(pattern: string): { regex: RegExp; names: string[] } {
|
|
|
125
126
|
return { regex: new RegExp(allOptional ? `^(?:${source}|/)$` : `^${source}$`), names };
|
|
126
127
|
}
|
|
127
128
|
|
|
129
|
+
// opts.staticBuild: set only by the static() build's in-process prerender worker
|
|
130
|
+
// (see PipelineConfig.staticBuild) — never by a deployed entry.
|
|
128
131
|
export function createWorker(
|
|
129
132
|
manifest: WorkerManifest,
|
|
133
|
+
opts: { staticBuild?: boolean } = {},
|
|
130
134
|
): { fetch(request: Request, env?: unknown, ctx?: WorkerExecutionContext): Promise<Response> } {
|
|
131
135
|
const dynamic: Compiled[] = (manifest.dynamicRoutes ?? []).map((d) => ({
|
|
132
136
|
...compilePattern(d.pattern),
|
|
@@ -212,6 +216,7 @@ export function createWorker(
|
|
|
212
216
|
agentSurface,
|
|
213
217
|
i18n: manifest.i18n,
|
|
214
218
|
routeList: () => routeList,
|
|
219
|
+
staticBuild: opts.staticBuild,
|
|
215
220
|
earlyHints: manifest.earlyHints,
|
|
216
221
|
htmlCacheControl: manifest.htmlCacheControl,
|
|
217
222
|
notFoundComponent: manifest.notFound,
|
|
@@ -282,7 +287,9 @@ export function createWorker(
|
|
|
282
287
|
// --- the deployed worker's outermost layer (run_worker_first) ---------------
|
|
283
288
|
// Prerendered pages are served as static ASSETS, which bypass the pipeline —
|
|
284
289
|
// so the agent-ready signals the asset layer can't produce get added HERE:
|
|
285
|
-
// 1.
|
|
290
|
+
// 1. a negotiated projection on a page (Accept: text/markdown / application/
|
|
291
|
+
// json → the prerendered .md / .json asset; else, and for the client
|
|
292
|
+
// router's fragment, the pipeline — never the page's HTML asset).
|
|
286
293
|
// 2. a `Link` header on every HTML response (RFC 8288/9727 discovery).
|
|
287
294
|
// 3. `x-markdown-tokens` on markdown responses.
|
|
288
295
|
// Static assets are served by the ASSETS binding (no re-render); only genuinely
|
|
@@ -293,6 +300,15 @@ type FetchPipeline = { fetch(request: Request, env?: unknown, ctx?: WorkerExecut
|
|
|
293
300
|
|
|
294
301
|
const estimateTokens = (s: string) => String(Math.ceil(s.length / 4));
|
|
295
302
|
|
|
303
|
+
// Add Accept to a response's Vary, keeping whatever the asset layer already set.
|
|
304
|
+
function varyAccept(headers: Headers): void {
|
|
305
|
+
const vary = headers.get("vary");
|
|
306
|
+
if (!vary) headers.set("vary", "accept");
|
|
307
|
+
else if (vary.trim() !== "*" && !vary.split(",").some((v) => v.trim().toLowerCase() === "accept")) {
|
|
308
|
+
headers.set("vary", `${vary}, accept`);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
296
312
|
export function withAssets(
|
|
297
313
|
pipeline: FetchPipeline,
|
|
298
314
|
opts: { link?: string | null } = {},
|
|
@@ -302,23 +318,40 @@ export function withAssets(
|
|
|
302
318
|
const assets = env?.ASSETS;
|
|
303
319
|
const url = new URL(request.url);
|
|
304
320
|
const isPagePath = !/\.[a-z0-9]+$/i.test(url.pathname); // no file extension
|
|
305
|
-
|
|
321
|
+
// The pipeline's own Accept decision (q-values included). A page path that
|
|
322
|
+
// negotiates a projection other than the HTML view must get THAT projection
|
|
323
|
+
// or the pipeline's answer for it — never the prerendered HTML asset.
|
|
324
|
+
const target = isPagePath ? acceptTarget(request.headers.get("accept") ?? "") : null;
|
|
306
325
|
|
|
307
|
-
// 1.
|
|
308
|
-
if (
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
const
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
326
|
+
// 1. Negotiated projections on a page path.
|
|
327
|
+
if (target && (request.method === "GET" || request.method === "HEAD")) {
|
|
328
|
+
// md / json → the prerendered <path>.md / <path>.json asset when the build
|
|
329
|
+
// emitted one (.md unless md = false; .json only for a json() route). Only
|
|
330
|
+
// the flat file — never <path>/index.*, a distinct /path/index route's twin
|
|
331
|
+
// (locale homes' <locale>/index.* are a static()-target artifact; this
|
|
332
|
+
// workers()-only layer never has them).
|
|
333
|
+
if (assets && request.method === "GET" && (target === "md" || target === "json")) {
|
|
334
|
+
const base = url.pathname === "/" ? "/index" : url.pathname.replace(/\/+$/, "");
|
|
335
|
+
const assetUrl = new URL(url);
|
|
336
|
+
assetUrl.pathname = `${base}.${target}`;
|
|
337
|
+
const a = await assets.fetch(new Request(assetUrl.toString(), { headers: request.headers }));
|
|
338
|
+
if (a.ok) {
|
|
339
|
+
const headers = new Headers(a.headers);
|
|
340
|
+
if (opts.link) headers.set("link", opts.link);
|
|
341
|
+
varyAccept(headers);
|
|
342
|
+
if (target === "json") return new Response(a.body, { status: 200, headers });
|
|
343
|
+
const body = await a.text();
|
|
344
|
+
headers.set("content-type", "text/markdown; charset=utf-8");
|
|
345
|
+
headers.set("x-markdown-tokens", estimateTokens(body));
|
|
346
|
+
return new Response(body, { status: 200, headers });
|
|
347
|
+
}
|
|
320
348
|
}
|
|
321
|
-
//
|
|
349
|
+
// No such asset (or a fragment, or HEAD) → the pipeline (step 3). It renders
|
|
350
|
+
// a dynamic route's projection, derives .json from the loader data, 404s a
|
|
351
|
+
// disabled projection, and renders the client router's soft-nav fragment —
|
|
352
|
+
// the HTML asset is a full DOCUMENT, which the router would morph into its
|
|
353
|
+
// [data-june-root] as if it were the root's inner HTML.
|
|
354
|
+
return pipeline.fetch(request, env, ctx);
|
|
322
355
|
}
|
|
323
356
|
|
|
324
357
|
// 2. Static assets (prerendered HTML/.md/.json, /client.js, hashed CSS)
|
|
@@ -335,10 +368,15 @@ export function withAssets(
|
|
|
335
368
|
// URL changes when the bytes do, so the browser may cache forever and
|
|
336
369
|
// never revalidate (no 304 round-trip, no stale window).
|
|
337
370
|
const immutable = /\.[a-f0-9]{8,}\.(css|js)$/.test(url.pathname);
|
|
338
|
-
|
|
371
|
+
// A page path answers HTML here but Markdown under Accept: text/markdown
|
|
372
|
+
// (step 1) — the same URL, so caches must key on Accept or they hand an
|
|
373
|
+
// agent the HTML (or a browser the Markdown).
|
|
374
|
+
const negotiated = isPagePath && ct.includes("text/html");
|
|
375
|
+
if (addLink || immutable || negotiated) {
|
|
339
376
|
const headers = new Headers(a.headers);
|
|
340
377
|
if (addLink) headers.set("link", opts.link!);
|
|
341
378
|
if (immutable) headers.set("cache-control", "public, max-age=31536000, immutable");
|
|
379
|
+
if (negotiated) varyAccept(headers);
|
|
342
380
|
return new Response(a.body, { status: a.status, headers });
|
|
343
381
|
}
|
|
344
382
|
return a;
|