@ogygia/core 0.12.2 → 0.13.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.
- package/dist/LateIsland.svelte +3 -2
- package/dist/LateIslandAwait.svelte +6 -2
- package/dist/Region.svelte +22 -33
- package/dist/boundary.d.ts +0 -2
- package/dist/boundary.js +8 -6
- package/dist/compiler/debarrel/barrel.d.ts +15 -8
- package/dist/compiler/debarrel/barrel.js +92 -45
- package/dist/compiler/debarrel/plugin.js +41 -17
- package/dist/compiler/dev/dev-hmr.d.ts +3 -0
- package/dist/compiler/dev/dev-hmr.js +3 -0
- package/dist/compiler/driver.js +11 -4
- package/dist/compiler/flags.js +21 -7
- package/dist/compiler/fouc-css.js +5 -1
- package/dist/compiler/kit.js +5 -1
- package/dist/compiler/link/build-output.js +12 -3
- package/dist/compiler/macros/bake.js +18 -4
- package/dist/compiler/macros/dollar.js +6 -1
- package/dist/compiler/macros/source.js +6 -1
- package/dist/compiler/macros/store.js +10 -2
- package/dist/compiler/macros/wire.js +6 -1
- package/dist/compiler/parse/scan.js +10 -3
- package/dist/compiler/region/transform.js +188 -74
- package/dist/context-bridge.js +13 -5
- package/dist/context.d.ts +9 -0
- package/dist/context.js +30 -1
- package/dist/document.d.ts +1 -1
- package/dist/document.js +7 -1
- package/dist/early-holes-head.d.ts +5 -0
- package/dist/early-holes-head.js +20 -0
- package/dist/early-holes.d.ts +34 -0
- package/dist/early-holes.js +51 -0
- package/dist/entry-hydrate.js +9 -12
- package/dist/events/bus.js +7 -2
- package/dist/events/schema.d.ts +2 -2
- package/dist/fn-transport.js +4 -3
- package/dist/hooks.js +94 -163
- package/dist/insights/page-assets.js +11 -3
- package/dist/insights/page-insights.d.ts +0 -2
- package/dist/insights/page-insights.js +14 -10
- package/dist/insights/session-insights.js +2 -2
- package/dist/internal-instruments.d.ts +3 -1
- package/dist/internal-instruments.js +3 -1
- package/dist/internal-server.d.ts +3 -2
- package/dist/internal-server.js +3 -2
- package/dist/internal.d.ts +1 -2
- package/dist/internal.js +1 -2
- package/dist/keep-fallback.d.ts +0 -2
- package/dist/keep-fallback.js +4 -5
- package/dist/live-transport.js +3 -2
- package/dist/messages/build.d.ts +585 -0
- package/dist/messages/build.js +800 -0
- package/dist/messages/core.d.ts +464 -0
- package/dist/messages/core.js +843 -0
- package/dist/messages/define.d.ts +62 -0
- package/dist/messages/define.js +49 -0
- package/dist/messages/index.d.ts +6 -0
- package/dist/messages/index.js +6 -0
- package/dist/messages/island.d.ts +4 -0
- package/dist/messages/island.js +34 -0
- package/dist/messages/lazy.d.ts +3 -0
- package/dist/messages/lazy.js +22 -0
- package/dist/messages/prose.d.ts +15 -0
- package/dist/messages/prose.js +43 -0
- package/dist/messages/server.d.ts +142 -0
- package/dist/messages/server.js +246 -0
- package/dist/nested.d.ts +3 -0
- package/dist/nested.js +8 -1
- package/dist/plugin/css.js +14 -13
- package/dist/plugin/facts.d.ts +2 -0
- package/dist/plugin/facts.js +10 -6
- package/dist/plugin/hooks.d.ts +7 -17
- package/dist/plugin/hooks.js +32 -4
- package/dist/plugin/index.d.ts +9 -2
- package/dist/plugin/request-scope.d.ts +20 -0
- package/dist/plugin/request-scope.js +149 -0
- package/dist/plugin/server.d.ts +20 -2
- package/dist/plugin/server.js +98 -28
- package/dist/plugin/testing.d.ts +6 -0
- package/dist/plugin/testing.js +14 -2
- package/dist/policies.d.ts +21 -0
- package/dist/policies.js +66 -0
- package/dist/preference.js +6 -1
- package/dist/preload.js +6 -9
- package/dist/ref-watch.d.ts +0 -10
- package/dist/ref-watch.js +14 -1
- package/dist/ref.js +17 -5
- package/dist/region-snippet.js +9 -3
- package/dist/region.js +2 -1
- package/dist/report-thrown.d.ts +9 -0
- package/dist/report-thrown.js +15 -0
- package/dist/rules.d.ts +17 -0
- package/dist/rules.js +57 -0
- package/dist/runtime/beacon.d.ts +0 -4
- package/dist/runtime/beacon.js +58 -43
- package/dist/runtime/boot-link.js +19 -2
- package/dist/runtime/client-hooks.js +2 -1
- package/dist/runtime/concurrency.d.ts +16 -5
- package/dist/runtime/concurrency.js +123 -7
- package/dist/runtime/core.d.ts +3 -1
- package/dist/runtime/core.js +718 -384
- package/dist/runtime/devalue-lane.d.ts +13 -0
- package/dist/runtime/devalue-lane.js +49 -0
- package/dist/runtime/disclose-version.d.ts +1 -0
- package/dist/runtime/disclose-version.js +14 -0
- package/dist/runtime/early-holes.d.ts +4 -0
- package/dist/runtime/early-holes.js +40 -0
- package/dist/runtime/entry-locations.js +40 -49
- package/dist/runtime/foreign-props.d.ts +0 -7
- package/dist/runtime/foreign-props.js +2 -1
- package/dist/runtime/form-continuity.d.ts +2 -2
- package/dist/runtime/form-continuity.js +30 -8
- package/dist/runtime/frame-nav.d.ts +7 -1
- package/dist/runtime/frame-nav.js +84 -18
- package/dist/runtime/frame-store.d.ts +25 -16
- package/dist/runtime/frame-store.js +124 -98
- package/dist/runtime/frames.js +8 -4
- package/dist/runtime/hole-facts.js +6 -7
- package/dist/runtime/hole-fetch.d.ts +17 -0
- package/dist/runtime/hole-fetch.js +47 -0
- package/dist/runtime/hydrate-core.d.ts +4 -4
- package/dist/runtime/hydrate-core.js +80 -64
- package/dist/runtime/import-again.d.ts +33 -0
- package/dist/runtime/import-again.js +217 -0
- package/dist/runtime/interaction-replay.d.ts +5 -3
- package/dist/runtime/interaction-replay.js +6 -6
- package/dist/runtime/interaction.d.ts +14 -3
- package/dist/runtime/interaction.js +46 -23
- package/dist/runtime/kit-page-thread.svelte.d.ts +2 -1
- package/dist/runtime/kit-page-thread.svelte.js +44 -20
- package/dist/runtime/lakes.d.ts +1 -1
- package/dist/runtime/lakes.js +18 -5
- package/dist/runtime/live.d.ts +1 -2
- package/dist/runtime/live.js +6 -8
- package/dist/runtime/load-scheduler.d.ts +29 -18
- package/dist/runtime/load-scheduler.js +236 -136
- package/dist/runtime/nav-handle.js +25 -6
- package/dist/runtime/navigation.d.ts +24 -0
- package/dist/runtime/navigation.js +24 -0
- package/dist/runtime/ownership.d.ts +1 -1
- package/dist/runtime/page-defer.js +3 -3
- package/dist/runtime/parse-html.d.ts +15 -4
- package/dist/runtime/parse-html.js +24 -5
- package/dist/runtime/pushable-props.svelte.d.ts +21 -0
- package/dist/runtime/pushable-props.svelte.js +37 -0
- package/dist/runtime/region-endpoint-url.js +4 -6
- package/dist/runtime/region-machines.d.ts +111 -0
- package/dist/runtime/region-machines.js +97 -0
- package/dist/runtime/region-sheets.d.ts +31 -0
- package/dist/runtime/region-sheets.js +49 -0
- package/dist/runtime/restore-report.d.ts +1 -0
- package/dist/runtime/restore-report.js +36 -0
- package/dist/runtime/restore.d.ts +5 -2
- package/dist/runtime/restore.js +33 -14
- package/dist/runtime/router-nav.d.ts +32 -12
- package/dist/runtime/router-nav.js +320 -228
- package/dist/runtime/router.d.ts +83 -19
- package/dist/runtime/router.js +297 -129
- package/dist/runtime/rules.d.ts +35 -0
- package/dist/runtime/rules.js +137 -0
- package/dist/runtime/schedule.d.ts +6 -3
- package/dist/runtime/schedule.js +172 -57
- package/dist/runtime/seeds.d.ts +5 -1
- package/dist/runtime/seeds.js +11 -5
- package/dist/runtime/session.d.ts +46 -7
- package/dist/runtime/session.js +78 -10
- package/dist/runtime/slots.d.ts +53 -20
- package/dist/runtime/slots.js +2 -3
- package/dist/runtime/soft-refresh.d.ts +16 -0
- package/dist/runtime/soft-refresh.js +14 -0
- package/dist/runtime/svelte-warnings.d.ts +4 -10
- package/dist/runtime/svelte-warnings.js +7 -4
- package/dist/runtime/wire-classes.js +21 -8
- package/dist/runtime/wire-format.js +6 -3
- package/dist/script.js +8 -7
- package/dist/seed-ref-reviver.d.ts +0 -9
- package/dist/seed-ref-reviver.js +2 -1
- package/dist/seed-refs.d.ts +46 -36
- package/dist/seed-refs.js +131 -92
- package/dist/server/document-tail.d.ts +6 -0
- package/dist/server/document-tail.js +7 -1
- package/dist/server/early-holes-csp.d.ts +14 -0
- package/dist/server/early-holes-csp.js +73 -0
- package/dist/server/page-facts.d.ts +4 -1
- package/dist/server/page-facts.js +4 -1
- package/dist/server/page-seed.d.ts +2 -2
- package/dist/server/page-seed.js +104 -11
- package/dist/server/page-stream.d.ts +14 -1
- package/dist/server/page-stream.js +119 -2
- package/dist/server/personal-response.d.ts +0 -5
- package/dist/server/personal-response.js +6 -2
- package/dist/server/props-wire.js +5 -1
- package/dist/server/region-endpoint.js +10 -2
- package/dist/server/render-cache.d.ts +24 -20
- package/dist/server/render-cache.js +99 -40
- package/dist/server/render-page.js +46 -15
- package/dist/server/request-stats.d.ts +10 -8
- package/dist/server/request-stats.js +20 -12
- package/dist/server/rules.d.ts +11 -0
- package/dist/server/rules.js +64 -0
- package/dist/server/signing-key.js +31 -18
- package/dist/server/stream-regions.d.ts +14 -1
- package/dist/server/stream-regions.js +38 -2
- package/dist/shared-state.js +5 -1
- package/dist/shims/app-navigation.js +3 -2
- package/dist/shims/page-store.svelte.js +16 -2
- package/dist/source.js +7 -2
- package/dist/store-transport.js +12 -5
- package/dist/transport.js +3 -2
- package/dist/vite/index.js +83 -74
- package/dist/vite/kit-dirs.js +7 -1
- package/dist/vite/options.d.ts +2 -1
- package/dist/vite/options.js +11 -20
- package/dist/vite/package-files.js +13 -3
- package/dist/vite/paths.d.ts +2 -0
- package/dist/vite/paths.js +4 -4
- package/dist/vite/plugin-api.d.ts +6 -5
- package/dist/vite/plugin-api.js +42 -14
- package/dist/vite/style-preprocess.js +10 -3
- package/package.json +8 -1
- package/dist/KeepHost.svelte +0 -19
- package/dist/KeepHost.svelte.d.ts +0 -10
- package/dist/LiveHost.svelte +0 -19
- package/dist/LiveHost.svelte.d.ts +0 -10
- package/dist/NestedProvider.svelte +0 -13
- package/dist/NestedProvider.svelte.d.ts +0 -8
- package/dist/runtime/page-cache.d.ts +0 -23
- package/dist/runtime/page-cache.js +0 -74
|
@@ -0,0 +1,800 @@
|
|
|
1
|
+
import { define_messages } from "./define.js";
|
|
2
|
+
import { prose } from "./prose.js";
|
|
3
|
+
// src/messages/build.ts
|
|
4
|
+
/**
|
|
5
|
+
* EVERY MESSAGE OGYGIA PRINTS AT BUILD TIME — the compiler and the Vite plugin, which run in Node
|
|
6
|
+
* (never in a page, so there is no production build to keep the wording out of): their code, their
|
|
7
|
+
* wording, what to do about them. Same calls as the runtime's (./core.ts):
|
|
8
|
+
*
|
|
9
|
+
* throw new OgygiaError('some_code', { file });
|
|
10
|
+
* warn('some_code', { file });
|
|
11
|
+
*
|
|
12
|
+
* The wording always prints, then the code's page `https://ogygiajs.dev/e/<code>?<args>`.
|
|
13
|
+
*/
|
|
14
|
+
const BUG = "An ogygia bug: please report it with the file that shows it.";
|
|
15
|
+
/** Retired `ogygia({ … })` keys, each with its new spelling: the config check throws
|
|
16
|
+
* `option_retired` for any of them (a legacy key that silently did nothing would un-tune real
|
|
17
|
+
* apps). */
|
|
18
|
+
const RETIRED_OPTIONS = {
|
|
19
|
+
regions: "`regions` is gone — its keys sit at the root now: write `visible`, `presets`, `ttl` and `maxPageAge` directly in `ogygia({ … })`.",
|
|
20
|
+
continuity: "`continuity` is gone — form continuity rides the router. Write `router: { forms: false }` to disable it.",
|
|
21
|
+
regionTtl: "`regionTtl` is `ttl` now — write `ogygia({ ttl: … })`.",
|
|
22
|
+
preload: "`preload` is gone — there is nothing to choose any more. The page carries each island’s chunk list as data, and the runtime preloads an island’s whole graph when it wakes (after the page has painted), so no island code moves before its wake and none waits on a waterfall after it. Remove the key.",
|
|
23
|
+
plugins: "`plugins` is gone — ogygia plugins are Vite plugins: list them beside `ogygia()` in vite.config, `plugins: [ogygia(), flags(), sveltekit()]`.",
|
|
24
|
+
freeze: "`freeze` is a plugin now, named postrender — install `@ogygia/postrender` and list `postrender({ ttl, default })` (from `@ogygia/postrender/vite`) beside `ogygia()` in vite.config `plugins`.",
|
|
25
|
+
content: "`content` is a plugin now — install `@ogygia/content` and list `content({ markdown, presets })` (from `@ogygia/content/vite`) beside `ogygia()` in vite.config `plugins`; the svelte config takes `preprocess()` / `extensions()` from there too.",
|
|
26
|
+
devtools: "`devtools` is a plugin now — install `@ogygia/devtools` and list `devtools()` (from `@ogygia/devtools/vite`) beside `ogygia()` in vite.config `plugins`; only where you want it, e.g. `...(mode !== 'production' ? [devtools()] : [])`.",
|
|
27
|
+
profiler: "`profiler` is part of the devtools plugin now — install `@ogygia/devtools` and list `devtools({ profiler: { … } })` (from `@ogygia/devtools/vite`) beside `ogygia()` in vite.config `plugins`."
|
|
28
|
+
};
|
|
29
|
+
/** The errors: `throw new OgygiaError(code, args)`. */
|
|
30
|
+
const BUILD_ERRORS = {
|
|
31
|
+
macro_store_misuse: {
|
|
32
|
+
text: (a) => prose`
|
|
33
|
+
${a.file}:${a.line} — ${a.problem}. import.meta.og.store is legal in exactly one shape: a
|
|
34
|
+
direct call wrapping a store factory — import.meta.og.store((seed) => ({ subscribe, … })).
|
|
35
|
+
It registers the factory under a build tag so islands rebuild the store THROUGH it (custom
|
|
36
|
+
methods survive); the factory's first parameter is the seed value.
|
|
37
|
+
`,
|
|
38
|
+
details: () => prose`
|
|
39
|
+
\`import.meta.og.store\` is a compile-time mark, not a value: it only works as a direct
|
|
40
|
+
call around a store factory, \`import.meta.og.store((seed) => writable(seed))\`. The
|
|
41
|
+
build registers that factory so an island rebuilds the store through it, custom methods
|
|
42
|
+
and all.
|
|
43
|
+
|
|
44
|
+
\`problem\` names what was written instead (no argument, two arguments, a bare
|
|
45
|
+
reference). Wrap the factory itself in one call.
|
|
46
|
+
`
|
|
47
|
+
},
|
|
48
|
+
macro_dollar_misuse: {
|
|
49
|
+
text: (a) => prose`
|
|
50
|
+
${a.file}:${a.line} — ${a.problem}. import.meta.og.$ is legal in exactly one shape: a
|
|
51
|
+
direct call wrapping an inline function — import.meta.og.$((args) => { … }). It hoists
|
|
52
|
+
that function so its VALUE can cross an island boundary as a handle.
|
|
53
|
+
`,
|
|
54
|
+
details: () => prose`
|
|
55
|
+
\`import.meta.og.$\` hoists a function into its own module so a handle to it can cross an
|
|
56
|
+
island boundary. The build has to see the function itself, so the mark only works as a
|
|
57
|
+
direct call around an inline function: \`import.meta.og.$((args) => ...)\`.
|
|
58
|
+
|
|
59
|
+
\`problem\` names what was written instead. Pass the function inline, as the one argument.
|
|
60
|
+
`
|
|
61
|
+
},
|
|
62
|
+
macro_wire_misuse: {
|
|
63
|
+
text: (a) => prose`
|
|
64
|
+
${a.file}:${a.line} — ${a.problem}. import.meta.og.wire is legal in exactly one position:
|
|
65
|
+
\`static wire = import.meta.og.wire({ encode, decode })\` inside a class body. The macro
|
|
66
|
+
consumes that member and mints the symbol key; the construct is not a value.
|
|
67
|
+
`,
|
|
68
|
+
details: () => prose`
|
|
69
|
+
\`import.meta.og.wire\` makes a class transportable across an island boundary. The build
|
|
70
|
+
replaces the member that holds it, so it only works in one place: a static member of a
|
|
71
|
+
class, \`static wire = import.meta.og.wire(codec)\`, where the codec has \`encode\` and
|
|
72
|
+
\`decode\`.
|
|
73
|
+
|
|
74
|
+
\`problem\` names what was written instead. Move the call into that member.
|
|
75
|
+
`
|
|
76
|
+
},
|
|
77
|
+
macro_source_misuse: {
|
|
78
|
+
text: (a) => prose`
|
|
79
|
+
${a.file}:${a.line} — ${a.problem}. import.meta.og.source is legal in exactly one
|
|
80
|
+
position: \`export const <name> = import.meta.og.source(fn)\` (optionally
|
|
81
|
+
\`(fn, { key })\`) at module top level. The compiler stamps the source id from that
|
|
82
|
+
export's identity.
|
|
83
|
+
`,
|
|
84
|
+
details: () => prose`
|
|
85
|
+
\`import.meta.og.source\` declares a data source. Its id is the file and export name it is
|
|
86
|
+
declared under, so the build only accepts it as the initializer of a top-level
|
|
87
|
+
\`export const\`: \`export const loadThing = import.meta.og.source(fn)\`.
|
|
88
|
+
|
|
89
|
+
\`problem\` names what was written instead. Declare the source as its own exported
|
|
90
|
+
constant.
|
|
91
|
+
`
|
|
92
|
+
},
|
|
93
|
+
macro_bake_arity: {
|
|
94
|
+
text: (a) => `${a.file}:${a.line} — import.meta.og.bake(fn) takes exactly one argument (a function).`,
|
|
95
|
+
details: () => prose`
|
|
96
|
+
\`import.meta.og.bake\` runs one function at build time and inlines its result. It takes
|
|
97
|
+
that function and nothing else: \`import.meta.og.bake(() => buildNav())\`.
|
|
98
|
+
`
|
|
99
|
+
},
|
|
100
|
+
macro_bake_not_function: {
|
|
101
|
+
text: (a) => `${a.file}:${a.line} — import.meta.og.bake(fn): the argument must be a function (\`() => …\`).`,
|
|
102
|
+
details: () => prose`
|
|
103
|
+
\`import.meta.og.bake\` was given something other than an inline function (a variable, a
|
|
104
|
+
value). The build evaluates the function's own source, so write it inline:
|
|
105
|
+
\`import.meta.og.bake(() => buildNav())\`.
|
|
106
|
+
`
|
|
107
|
+
},
|
|
108
|
+
macro_bake_eval_failed: {
|
|
109
|
+
text: (a) => prose`
|
|
110
|
+
import.meta.og.bake() in ${a.file}: evaluating the function failed — ${a.reason}. A baked
|
|
111
|
+
function may use this module's IMPORTS and literals only (not its other local variables),
|
|
112
|
+
and must not touch runtime-only modules ($app/*, the browser).
|
|
113
|
+
`,
|
|
114
|
+
details: () => prose`
|
|
115
|
+
The build bundled the baked function with the module's imports and ran it, and it threw.
|
|
116
|
+
\`reason\` is the error.
|
|
117
|
+
|
|
118
|
+
The function runs alone, at build time: it sees the module's imports and literals, not its
|
|
119
|
+
other local variables, and there is no request, no \`$app/*\` module and no browser. Move
|
|
120
|
+
what it needs into an import.
|
|
121
|
+
`
|
|
122
|
+
},
|
|
123
|
+
macro_bake_not_serializable: {
|
|
124
|
+
text: (a) => prose`
|
|
125
|
+
${a.file}:${a.line} — import.meta.og.bake(): the result is not serializable (${a.reason}).
|
|
126
|
+
bake produces DATA — return plain values (JSON + Date/Map/Set/RegExp/BigInt), never a
|
|
127
|
+
function, Promise, or class instance.
|
|
128
|
+
`,
|
|
129
|
+
details: () => prose`
|
|
130
|
+
The baked function ran, but its result cannot be written into the module as a constant.
|
|
131
|
+
\`reason\` names the value that failed.
|
|
132
|
+
|
|
133
|
+
Return plain data: JSON values, \`Date\`, \`Map\`, \`Set\`, \`RegExp\`, \`BigInt\`. A
|
|
134
|
+
function, a promise or a class instance cannot be baked.
|
|
135
|
+
`
|
|
136
|
+
},
|
|
137
|
+
kit_config_not_literal: {
|
|
138
|
+
text: (a) => `${a.file}: \`config.${a.key}\` must be a literal (true, false, a number, a string or null) — ogygia reads it at build time.`,
|
|
139
|
+
details: () => prose`
|
|
140
|
+
ogygia reads some keys of a route's \`export const config\` while it builds, from the
|
|
141
|
+
source. This one is an expression (a variable, a call), which only has a value when the
|
|
142
|
+
app runs. Write the value itself: \`true\`, \`false\`, a number, a string or \`null\`.
|
|
143
|
+
`
|
|
144
|
+
},
|
|
145
|
+
island_import_unresolved: {
|
|
146
|
+
text: (a) => prose`
|
|
147
|
+
cannot resolve '${a.specifier}' imported by the generated island module for ${a.host}.
|
|
148
|
+
That island was marked on a package import, so the specifier must resolve from the host
|
|
149
|
+
file: check the package is installed and its "exports" map exposes this subpath (with a
|
|
150
|
+
"svelte" condition for .svelte components).
|
|
151
|
+
`,
|
|
152
|
+
details: () => prose`
|
|
153
|
+
An island was marked on an import from a package, and the module ogygia generates for it
|
|
154
|
+
imports that same specifier. It does not resolve from the file that marked it.
|
|
155
|
+
|
|
156
|
+
Check the package is installed in the app, and that its \`exports\` map lists this
|
|
157
|
+
subpath, with a \`svelte\` condition for a \`.svelte\` component.
|
|
158
|
+
`
|
|
159
|
+
},
|
|
160
|
+
call_arg_not_literal: {
|
|
161
|
+
text: (a) => `${a.call}: the first argument must be a static string literal, got '${a.got}…'`,
|
|
162
|
+
details: () => prose`
|
|
163
|
+
The build reads this call's first argument from the source, so it has to be a plain
|
|
164
|
+
string, written out. \`got\` is what was written instead (a variable, a call). Put the
|
|
165
|
+
string itself there.
|
|
166
|
+
`
|
|
167
|
+
},
|
|
168
|
+
call_arg_interpolated: {
|
|
169
|
+
text: (a) => prose`
|
|
170
|
+
${a.call}: the first argument must be a static string literal — a template literal with
|
|
171
|
+
\${…} interpolation is a runtime value the build cannot resolve.
|
|
172
|
+
`,
|
|
173
|
+
details: () => prose`
|
|
174
|
+
The build reads this call's first argument from the source. A template literal with a
|
|
175
|
+
value inside it only has its text when the app runs. Write one plain string.
|
|
176
|
+
`
|
|
177
|
+
},
|
|
178
|
+
call_arg_in_expression: {
|
|
179
|
+
text: (a) => prose`
|
|
180
|
+
${a.call}: the first argument must be a static string literal, but it is part of a larger
|
|
181
|
+
expression (near '${a.near}…'). Use one plain string.
|
|
182
|
+
`,
|
|
183
|
+
details: () => prose`
|
|
184
|
+
The build reads this call's first argument from the source. Here the string is joined
|
|
185
|
+
with something else (\`'./' + dir\`, a \`.concat()\` call), which only has its value when
|
|
186
|
+
the app runs. Write the whole string out.
|
|
187
|
+
`
|
|
188
|
+
},
|
|
189
|
+
import_key_invalid: {
|
|
190
|
+
text: (a) => `importKeys.${a.role} must be a non-empty JS identifier (got ${a.got}).`,
|
|
191
|
+
details: () => prose`
|
|
192
|
+
\`importKeys\` renames the import attributes ogygia reads (\`wake\`, \`fetch\`,
|
|
193
|
+
\`render\`, \`preset\`, \`region\`). Each name is written as a key inside \`with\`, so it
|
|
194
|
+
has to be a JavaScript identifier.
|
|
195
|
+
`
|
|
196
|
+
},
|
|
197
|
+
import_keys_not_distinct: {
|
|
198
|
+
text: () => "importKeys.wake, importKeys.fetch, importKeys.render, importKeys.preset, and importKeys.region must be distinct.",
|
|
199
|
+
details: () => prose`
|
|
200
|
+
Two of the attribute names in \`importKeys\` are the same, so the build could not tell
|
|
201
|
+
which one an import means. Give each its own name.
|
|
202
|
+
`
|
|
203
|
+
},
|
|
204
|
+
region_value_not_raw: {
|
|
205
|
+
text: (a) => prose`
|
|
206
|
+
${a.host}: \`${a.key}\` only takes the value 'raw' (a held region with no baked
|
|
207
|
+
schedule). To bake a schedule use a \`wake:\` mark, or set it at the \`region()\` call.
|
|
208
|
+
`,
|
|
209
|
+
details: () => prose`
|
|
210
|
+
The \`region\` import attribute marks a held region and has one value, \`'raw'\`. It
|
|
211
|
+
carries no schedule. To give the region one, mark the import with \`wake\` instead, or
|
|
212
|
+
pass \`wake\` where it is placed: \`region(C, props, opts)\`.
|
|
213
|
+
`
|
|
214
|
+
},
|
|
215
|
+
wake_strategy_unknown: {
|
|
216
|
+
text: (a) => `${a.host}: unknown \`${a.key}\` strategy '${a.value}'. Use 'load' | 'idle' | 'visible' | 'interaction' | a media query.`,
|
|
217
|
+
details: () => prose`
|
|
218
|
+
A \`wake\` mark says when an island's JavaScript runs. It takes \`'load'\`, \`'idle'\`,
|
|
219
|
+
\`'visible'\`, \`'interaction'\` or a media query such as \`'(min-width: 800px)'\`.
|
|
220
|
+
`
|
|
221
|
+
},
|
|
222
|
+
generated_module_relative_import: {
|
|
223
|
+
text: (a) => prose`
|
|
224
|
+
${a.host}: cannot resolve the relative import '${a.specifier}' from a generated module —
|
|
225
|
+
it has no directory. Its real origin must be threaded (HostCtx.originOf); this is an
|
|
226
|
+
ogygia bug, please report it.
|
|
227
|
+
`,
|
|
228
|
+
details: () => BUG
|
|
229
|
+
},
|
|
230
|
+
region_import_invalid: {
|
|
231
|
+
text: (a) => `${a.host}: import { ${a.names} } — ${a.problem}`,
|
|
232
|
+
details: () => prose`
|
|
233
|
+
A marked import (one with \`wake\`, \`render\`, \`fetch\`, \`preset\` or \`region\` in
|
|
234
|
+
its \`with\` clause) is written in a way the build cannot turn into a region. \`problem\`
|
|
235
|
+
says what is wrong and what to write.
|
|
236
|
+
`
|
|
237
|
+
},
|
|
238
|
+
as_region_invalid: {
|
|
239
|
+
text: (a) => `${a.host}: import.meta.og.asRegion (${a.name}) — ${a.problem}`,
|
|
240
|
+
details: () => prose`
|
|
241
|
+
\`import.meta.og.asRegion\` marks a component as a region, like a marked import. It only
|
|
242
|
+
works on a plain \`const Name = import.meta.og.asRegion(Component, options)\`, with the
|
|
243
|
+
same options an import's \`with\` clause takes. \`problem\` says what is wrong.
|
|
244
|
+
`
|
|
245
|
+
},
|
|
246
|
+
region_children_not_portable: {
|
|
247
|
+
text: (a) => prose`
|
|
248
|
+
${a.host}: <${a.tag}> has host children/snippets that cannot cross the island boundary.
|
|
249
|
+
Under portable bindings, pass serializable props and put UI inside the island
|
|
250
|
+
component${a.server ? " (only the reserved `{#snippet ogygiaFallback()}` may appear at the call site)." : "."}
|
|
251
|
+
`,
|
|
252
|
+
details: () => prose`
|
|
253
|
+
A deferred region or a held region renders on its own, from its props alone, so markup
|
|
254
|
+
written between its tags has nowhere to go. Pass the data as props and put the markup
|
|
255
|
+
inside the component.
|
|
256
|
+
|
|
257
|
+
A deferred region may keep one snippet at the call site: \`ogygiaFallback\`, what shows
|
|
258
|
+
until its HTML arrives.
|
|
259
|
+
`
|
|
260
|
+
},
|
|
261
|
+
region_dotted_tag: {
|
|
262
|
+
text: (a) => prose`
|
|
263
|
+
${a.host}: dotted tag \`<${a.tag}>\` is not supported for region import '${a.import}'.
|
|
264
|
+
Import the leaf component with \`with { hydrate|defer }\` instead.
|
|
265
|
+
`,
|
|
266
|
+
details: () => prose`
|
|
267
|
+
A marked import becomes one region, so the build cannot reach a component hanging off it
|
|
268
|
+
(\`Menu.Item\`). Import that component on its own and mark that import.
|
|
269
|
+
`
|
|
270
|
+
},
|
|
271
|
+
dynamic_region_import: {
|
|
272
|
+
text: (a) => prose`
|
|
273
|
+
${a.host}: dynamic import() with { with: { ${a.keys} } } is not supported. Mark islands
|
|
274
|
+
with a static \`import X from '…' with { ${a.wake_key}: '…' }\` (or \`${a.render_key}\` /
|
|
275
|
+
\`${a.preset_key}\`) — the binding becomes a portable island component. For a
|
|
276
|
+
click-loaded chunk that is not an island, use plain \`await import('./Comp.svelte')\` (no
|
|
277
|
+
region attributes) inside a host island. To delay a real island until click, gate a static
|
|
278
|
+
region import with \`{#if}\`.
|
|
279
|
+
`,
|
|
280
|
+
details: () => prose`
|
|
281
|
+
A region needs a static import and a tag the server can render, so region attributes on
|
|
282
|
+
a dynamic \`import()\` do nothing (Vite drops them). Use a static marked import.
|
|
283
|
+
|
|
284
|
+
To load a plain component on click, call \`await import('./Comp.svelte')\` with no region
|
|
285
|
+
attributes, inside an island. To delay an island, put its tag behind an \`if\` block.
|
|
286
|
+
`
|
|
287
|
+
},
|
|
288
|
+
region_import_no_specifier: {
|
|
289
|
+
text: (a) => `${a.host}: ${a.held ? "held-region import" : "region import"} '${a.name}' needs a module specifier ($lib/…, relative, or a package specifier like 'pkg/component').`,
|
|
290
|
+
details: () => prose`
|
|
291
|
+
A marked import has no module path the build can resolve. Import the component from
|
|
292
|
+
\`$lib/...\`, a relative path, or a package subpath such as \`'pkg/component'\`.
|
|
293
|
+
`
|
|
294
|
+
},
|
|
295
|
+
snippet_reads_dollar_props: {
|
|
296
|
+
text: (a) => prose`
|
|
297
|
+
${a.host}: {#snippet ${a.snippet}} crosses an island boundary but reads \`${a.name}\` —
|
|
298
|
+
the host's $$-props cannot cross. Read the value into a plain host variable outside the
|
|
299
|
+
snippet and use that instead.
|
|
300
|
+
`,
|
|
301
|
+
details: () => prose`
|
|
302
|
+
A snippet passed into an island is rendered from the values it captures. \`$$props\` and
|
|
303
|
+
\`$$restProps\` belong to the host component and cannot be captured. Read what the
|
|
304
|
+
snippet needs into a plain variable in the host, outside the snippet, and use that.
|
|
305
|
+
`
|
|
306
|
+
},
|
|
307
|
+
held_fetch_without_render: {
|
|
308
|
+
text: (a) => prose`
|
|
309
|
+
${a.host}: \`${a.fetch_key}: '${a.value}'\` without \`${a.render_key}: 'deferred'\` —
|
|
310
|
+
\`${a.fetch_key}\` is a hole's timing. Write \`${a.render_key}: 'deferred',
|
|
311
|
+
${a.fetch_key}: '${a.value}'\` for a hole, or \`${a.wake_key}: '${a.value}'\` for an
|
|
312
|
+
island.
|
|
313
|
+
`,
|
|
314
|
+
details: () => prose`
|
|
315
|
+
\`fetch\` says when a deferred region's (a hole's) HTML arrives, so it only goes with
|
|
316
|
+
\`render: 'deferred'\`. For a hole, write both. For an island that runs its JavaScript
|
|
317
|
+
at that time, write \`wake\` instead.
|
|
318
|
+
`
|
|
319
|
+
},
|
|
320
|
+
held_render_live: {
|
|
321
|
+
text: (a) => `${a.host}: \`${a.render_key}: 'live'\` is not supported on a .ts import — use it in a .svelte file.`,
|
|
322
|
+
details: () => prose`
|
|
323
|
+
A live region is placed by a Svelte component. A \`.ts\` or \`.js\` module can only hand
|
|
324
|
+
out held regions and holes, so mark the import in a \`.svelte\` file.
|
|
325
|
+
`
|
|
326
|
+
},
|
|
327
|
+
held_render_unknown: {
|
|
328
|
+
text: (a) => `${a.host}: unknown \`${a.render_key}\` '${a.value}'. Use 'deferred'.`,
|
|
329
|
+
details: () => prose`
|
|
330
|
+
In a \`.ts\` or \`.js\` module, \`render\` takes one value, \`'deferred'\`: a hole whose
|
|
331
|
+
HTML is fetched from the server.
|
|
332
|
+
`
|
|
333
|
+
},
|
|
334
|
+
held_hole_timed_twice: {
|
|
335
|
+
text: (a) => prose`
|
|
336
|
+
${a.host}: a \`${a.render_key}: 'deferred'\` hole timed twice, with \`${a.fetch_key}:
|
|
337
|
+
'${a.fetch}'\` and \`${a.wake_key}: '${a.wake}'\`. Keep \`${a.fetch_key}\`: it says when a
|
|
338
|
+
hole's HTML arrives.
|
|
339
|
+
`,
|
|
340
|
+
details: () => prose`
|
|
341
|
+
A hole has one timing, \`fetch\`. The old spelling, \`wake\` on a hole, is still read,
|
|
342
|
+
but with both the build cannot tell which one is meant. Remove \`wake\`.
|
|
343
|
+
`
|
|
344
|
+
},
|
|
345
|
+
held_fetch_not_timing: {
|
|
346
|
+
text: (a) => prose`
|
|
347
|
+
${a.host}: \`${a.fetch_key}: '${a.value}'\` is not a timing. Use \`${a.fetch_key}: 'load'
|
|
348
|
+
| 'idle' | 'visible' | 'interaction'\` or a media query (a hole must fetch — not 'none').
|
|
349
|
+
`,
|
|
350
|
+
details: () => prose`
|
|
351
|
+
\`fetch\` says when a hole's HTML arrives: \`'load'\`, \`'idle'\`, \`'visible'\`,
|
|
352
|
+
\`'interaction'\` or a media query. A hole always fetches, so \`'none'\` is not one.
|
|
353
|
+
`
|
|
354
|
+
},
|
|
355
|
+
held_marker_mixed: {
|
|
356
|
+
text: (a) => prose`
|
|
357
|
+
${a.host}: a held-region import on '${a.name}' takes ONE marker — \`${a.region_key}:
|
|
358
|
+
'raw'\`, \`${a.wake_key}: '…'\`, or \`${a.render_key}: 'deferred'\` (with
|
|
359
|
+
\`${a.fetch_key}\` as its timing).
|
|
360
|
+
`,
|
|
361
|
+
details: () => prose`
|
|
362
|
+
An import in a \`.ts\` or \`.js\` module is one kind of held region: \`region: 'raw'\`
|
|
363
|
+
(no schedule), \`wake\` (an island) or \`render: 'deferred'\` (a hole, timed by
|
|
364
|
+
\`fetch\`). Keep the one you mean.
|
|
365
|
+
`
|
|
366
|
+
},
|
|
367
|
+
option_retired: {
|
|
368
|
+
text: (a) => RETIRED_OPTIONS[a.option] ?? `\`${a.option}\` is gone.`,
|
|
369
|
+
details: () => prose`
|
|
370
|
+
An \`ogygia()\` option from an earlier version was passed. It is refused rather than
|
|
371
|
+
ignored, so nothing silently stops working. The message says what replaced it.
|
|
372
|
+
`
|
|
373
|
+
},
|
|
374
|
+
preset_empty: {
|
|
375
|
+
text: (a) => `presets.${a.name} is empty — a preset with nothing is a mistake.`,
|
|
376
|
+
details: () => prose`
|
|
377
|
+
A region preset names a set of import options (\`with { preset: 'card' }\`). This one sets
|
|
378
|
+
none. Give it its options, or remove it.
|
|
379
|
+
`
|
|
380
|
+
},
|
|
381
|
+
preset_key_unknown: {
|
|
382
|
+
text: (a) => `presets.${a.name}: unknown key \`${a.key}\`. A preset takes ${a.allowed}.`,
|
|
383
|
+
details: () => prose`
|
|
384
|
+
A region preset holds the options a marked import takes. \`key\` is not one of them;
|
|
385
|
+
\`allowed\` lists those that are.
|
|
386
|
+
`
|
|
387
|
+
},
|
|
388
|
+
max_page_age_invalid: {
|
|
389
|
+
text: (a) => prose`
|
|
390
|
+
maxPageAge must be a number of seconds ≥ 0 (got ${a.value}). Write e.g. \`30 * 24 *
|
|
391
|
+
3600\` for 30 days, or \`0\` to turn renewal off.
|
|
392
|
+
`,
|
|
393
|
+
details: () => prose`
|
|
394
|
+
\`maxPageAge\` is how long, in seconds, a page's expired region addresses may still be
|
|
395
|
+
renewed. Write a number, such as \`30 * 24 * 3600\` for 30 days, or \`0\` to never renew.
|
|
396
|
+
`
|
|
397
|
+
},
|
|
398
|
+
secret_too_short: {
|
|
399
|
+
text: (a) => `OGYGIA_SECRET is too short for production builds (need ≥${a.min_bytes} UTF-8 bytes).`,
|
|
400
|
+
details: () => prose`
|
|
401
|
+
\`OGYGIA_SECRET\` signs region addresses. A short key can be guessed, so a production
|
|
402
|
+
build refuses it (dev accepts any). Use a long random value, such as the output of
|
|
403
|
+
\`openssl rand -base64 32\`.
|
|
404
|
+
`
|
|
405
|
+
},
|
|
406
|
+
kit_remote_src_missing: {
|
|
407
|
+
text: () => "could not locate Kit's client remote-functions (src). Use an @sveltejs/kit that publishes its `src/` (2.70.2 or later, or 3.x).",
|
|
408
|
+
details: () => prose`
|
|
409
|
+
ogygia reuses SvelteKit's own client code for remote functions, from the \`src/\` folder
|
|
410
|
+
Kit publishes. This version of \`@sveltejs/kit\` does not ship it. Upgrade to 2.70.2 or
|
|
411
|
+
later.
|
|
412
|
+
`
|
|
413
|
+
},
|
|
414
|
+
package_files_not_array: {
|
|
415
|
+
text: (a) => prose`
|
|
416
|
+
${a.package}: \`"ogygia": { "files": […] }\` must be an array of package-relative
|
|
417
|
+
paths/globs (like npm's "files") — got ${a.got}.
|
|
418
|
+
`,
|
|
419
|
+
details: () => prose`
|
|
420
|
+
A package puts its files on ogygia's compile surface with \`ogygia.files\` in its
|
|
421
|
+
\`package.json\`: a list of paths or globs inside the package, like npm's \`files\`.
|
|
422
|
+
This one is not a list of strings.
|
|
423
|
+
`
|
|
424
|
+
},
|
|
425
|
+
package_files_escapes: {
|
|
426
|
+
text: (a) => `${a.package}: ogygia.files entry '${a.entry}' escapes the package.`,
|
|
427
|
+
details: () => prose`
|
|
428
|
+
An \`ogygia.files\` entry points outside its own package (\`../\`), which would compile
|
|
429
|
+
code the package does not own. List paths inside the package only.
|
|
430
|
+
`
|
|
431
|
+
},
|
|
432
|
+
plugin_without_ogygia: {
|
|
433
|
+
text: (a) => `\`${a.plugin}\` is listed in vite.config but \`ogygia()\` is not — add \`ogygia()\` from \`ogygia/vite\` to \`plugins\`.`,
|
|
434
|
+
details: () => prose`
|
|
435
|
+
An ogygia plugin runs inside \`ogygia()\`, so it does nothing alone. Import \`ogygia\`
|
|
436
|
+
from \`ogygia/vite\` and list \`ogygia()\` first in \`plugins\`.
|
|
437
|
+
`
|
|
438
|
+
},
|
|
439
|
+
plugin_factory_not_called: {
|
|
440
|
+
text: () => "a function is listed in vite.config `plugins` — call the factory: `flags()`, not `flags`.",
|
|
441
|
+
details: () => prose`
|
|
442
|
+
A plugin is listed by its factory's name without calling it. Add the parentheses:
|
|
443
|
+
\`flags()\`, not \`flags\`.
|
|
444
|
+
`
|
|
445
|
+
},
|
|
446
|
+
plugin_after_sveltekit: {
|
|
447
|
+
text: (a) => `\`${a.plugin}\` is listed after \`sveltekit()\` in vite.config — list \`ogygia()\` and its plugins first: \`plugins: [ogygia(), flags(), sveltekit()]\`.`,
|
|
448
|
+
details: () => prose`
|
|
449
|
+
Vite runs plugins in the order they are listed. ogygia and its plugins must see each
|
|
450
|
+
module before SvelteKit does, so list them first:
|
|
451
|
+
\`plugins: [ogygia(), flags(), sveltekit()]\`.
|
|
452
|
+
`
|
|
453
|
+
},
|
|
454
|
+
plugin_name_missing: {
|
|
455
|
+
text: () => "a plugin definition needs a `name` (its package name).",
|
|
456
|
+
details: () => prose`
|
|
457
|
+
\`definePlugin()\` was called without a \`name\`. The name is the plugin's package name:
|
|
458
|
+
ogygia resolves the package by it.
|
|
459
|
+
`
|
|
460
|
+
},
|
|
461
|
+
plugin_listed_twice: {
|
|
462
|
+
text: (a) => `plugin \`${a.plugin}\` is listed twice.`,
|
|
463
|
+
details: () => "The same ogygia plugin appears twice in `plugins`. List it once, with all its options."
|
|
464
|
+
},
|
|
465
|
+
plugin_realm_not_location: {
|
|
466
|
+
text: (a) => `plugin \`${a.plugin}\`: \`${a.realm}\` is a module location — \`import.meta.resolve('./${a.realm}.ts')\`.`,
|
|
467
|
+
details: () => prose`
|
|
468
|
+
A plugin's \`server\` and \`client\` name the module that runs there, as a location, not
|
|
469
|
+
the module itself. Resolve it next to the factory:
|
|
470
|
+
\`server: import.meta.resolve('./server.ts')\`.
|
|
471
|
+
`
|
|
472
|
+
},
|
|
473
|
+
plugin_options_not_json: {
|
|
474
|
+
text: (a) => `plugin \`${a.plugin}\`: \`options\` must be plain JSON (configure live objects in hooks.server.ts).`,
|
|
475
|
+
details: () => prose`
|
|
476
|
+
A plugin's \`options\` are written into the server build, so they must survive
|
|
477
|
+
\`JSON.stringify\`. Set up live objects (clients, functions) in \`hooks.server.ts\`
|
|
478
|
+
instead.
|
|
479
|
+
`
|
|
480
|
+
},
|
|
481
|
+
plugin_realm_not_file: {
|
|
482
|
+
text: (a) => `plugin \`${a.plugin}\`: its \`${a.realm}\` realm \`${a.location}\` is not a file — resolve it next to the factory: \`import.meta.resolve('./${a.realm}.ts')\`.`,
|
|
483
|
+
details: () => prose`
|
|
484
|
+
A plugin's \`server\` or \`client\` location does not point at a file. Resolve it next to
|
|
485
|
+
the factory, so it is the file the package ships:
|
|
486
|
+
\`import.meta.resolve('./server.ts')\`.
|
|
487
|
+
`
|
|
488
|
+
},
|
|
489
|
+
plugin_package_unresolved: {
|
|
490
|
+
text: (a) => `plugin \`${a.plugin}\`: no package by that name resolves from ${a.root} — its name must be its package name.`,
|
|
491
|
+
details: () => prose`
|
|
492
|
+
A plugin's \`name\` is its package name, and ogygia resolves the package by it from the
|
|
493
|
+
app. Nothing by that name is installed there: install the package, or fix the name.
|
|
494
|
+
`
|
|
495
|
+
},
|
|
496
|
+
route_config_key_invalid: {
|
|
497
|
+
text: (a) => `plugin \`${a.plugin}\`: route config key \`${a.key}\` must be a camelCase identifier.`,
|
|
498
|
+
details: () => prose`
|
|
499
|
+
A plugin claimed a key of a route's \`export const config\` that is not a camelCase name.
|
|
500
|
+
Use one such as \`postrender\`.
|
|
501
|
+
`
|
|
502
|
+
},
|
|
503
|
+
route_config_key_claimed: {
|
|
504
|
+
text: (a) => `route config key \`${a.key}\` is claimed by both \`${a.owner}\` and \`${a.plugin}\`.`,
|
|
505
|
+
details: () => prose`
|
|
506
|
+
Two plugins claimed the same key of a route's \`export const config\`, so a route could
|
|
507
|
+
not say which one it configures. One of them has to use another key.
|
|
508
|
+
`
|
|
509
|
+
},
|
|
510
|
+
plugin_macro_name_invalid: {
|
|
511
|
+
text: (a) => `plugin \`${a.plugin}\`: macro \`import.meta.og.${a.name}\` must be a camelCase name core does not own.`,
|
|
512
|
+
details: () => prose`
|
|
513
|
+
A plugin's macro is a camelCase name under \`import.meta.og\`. The names \`wire\`,
|
|
514
|
+
\`$\`, \`source\`, \`store\` and \`bake\` are ogygia's own.
|
|
515
|
+
`
|
|
516
|
+
},
|
|
517
|
+
plugin_macro_claimed: {
|
|
518
|
+
text: (a) => `macro \`import.meta.og.${a.name}\` is claimed by both \`${a.owner}\` and \`${a.plugin}\`.`,
|
|
519
|
+
details: () => prose`
|
|
520
|
+
Two plugins registered the same \`import.meta.og\` macro. One of them has to use another
|
|
521
|
+
name.
|
|
522
|
+
`
|
|
523
|
+
},
|
|
524
|
+
page_modules_not_absolute: {
|
|
525
|
+
text: (a) => `plugin \`${a.plugin}\`: \`pageModules({ files })\` takes absolute paths (got \`${a.file}\`).`,
|
|
526
|
+
details: () => prose`
|
|
527
|
+
\`pageModules\` was given a relative file path. Pass absolute paths, for example
|
|
528
|
+
resolved from the app's root.
|
|
529
|
+
`
|
|
530
|
+
},
|
|
531
|
+
request_event_server_only: {
|
|
532
|
+
text: () => "getRequestEvent is server-only",
|
|
533
|
+
details: () => prose`
|
|
534
|
+
\`getRequestEvent()\` was called in the browser. There is no request there: a deferred
|
|
535
|
+
region's HTML is fetched from the server, so read the request in the component that
|
|
536
|
+
renders on the server, and pass what the browser needs as props. (The build writes this
|
|
537
|
+
message into the browser's stub, so it prints in the page.)
|
|
538
|
+
`
|
|
539
|
+
}
|
|
540
|
+
};
|
|
541
|
+
/** The warnings: `warn(code, args, ...rest)`; and, at its end, the build's reports, which print
|
|
542
|
+
* their `line(code, args)` at info level. */
|
|
543
|
+
const BUILD_WARNINGS = {
|
|
544
|
+
macro_store_returns_non_store: {
|
|
545
|
+
text: (a) => prose`
|
|
546
|
+
${a.file}:${a.line} — this import.meta.og.store factory has a return that is provably not
|
|
547
|
+
a store (undefined/null/primitive). Where that branch runs, the product crosses as plain
|
|
548
|
+
data, unbranded. If it is an environment guard, return a store there too (e.g.
|
|
549
|
+
writable(seed)) and guard the side effects inside the factory instead.
|
|
550
|
+
`,
|
|
551
|
+
details: () => prose`
|
|
552
|
+
A store factory marked with \`import.meta.og.store\` returns something that is not a
|
|
553
|
+
store on one branch (\`undefined\`, \`null\`, a number). Where that branch runs, the
|
|
554
|
+
value reaches islands as plain data, not as the store.
|
|
555
|
+
|
|
556
|
+
If the branch guards an environment (the server), return a store there too, such as
|
|
557
|
+
\`writable(seed)\`, and guard the side effects inside the factory.
|
|
558
|
+
`
|
|
559
|
+
},
|
|
560
|
+
scoped_css_failed: {
|
|
561
|
+
text: (a) => `scoped CSS for ${a.file} could not be compiled (${a.reason}) — shipping its style bodies unscoped`,
|
|
562
|
+
details: () => prose`
|
|
563
|
+
ogygia compiles a component's styles on their own to ship them with its HTML, and that
|
|
564
|
+
compile failed (\`reason\`). The styles ship without Svelte's scoping, so its rules can
|
|
565
|
+
reach the rest of the page. Fix the component so it compiles.
|
|
566
|
+
`
|
|
567
|
+
},
|
|
568
|
+
package_marks_undeclared: {
|
|
569
|
+
text: (a) => prose`
|
|
570
|
+
${a.file} uses ogygia marks, but its package declares no \`"ogygia": { "files": [...] }\`
|
|
571
|
+
— the marks are IGNORED. Add the field to that package's package.json
|
|
572
|
+
(npm-"files"-style paths/globs) to put it on ogygia's compile surface.
|
|
573
|
+
`,
|
|
574
|
+
details: () => prose`
|
|
575
|
+
A file in a dependency marks imports for ogygia (\`with { wake }\`), but ogygia only
|
|
576
|
+
compiles a package's files when the package asks for it. So the marks do nothing.
|
|
577
|
+
|
|
578
|
+
Add \`ogygia.files\` to that package's \`package.json\`: the paths or globs ogygia
|
|
579
|
+
compiles, like npm's \`files\`.
|
|
580
|
+
`
|
|
581
|
+
},
|
|
582
|
+
island_context_unprovided: {
|
|
583
|
+
text: (a) => prose`
|
|
584
|
+
island code ${a.file} reads getContext('${a.key}'), but this app registers no ogygia
|
|
585
|
+
context provider and no island code sets '${a.key}'. On a csr=false page a value set with
|
|
586
|
+
Svelte's setContext in a page/layout does NOT cross the island boundary — the island reads
|
|
587
|
+
undefined on the client, re-renders a different tree, and Svelte discards its
|
|
588
|
+
server-rendered DOM on hydration (a silent full re-render). Fix: provide '${a.key}' with
|
|
589
|
+
setContext / <Provide> / createContext imported from 'ogygia' (in a csr=false layout); the
|
|
590
|
+
read stays getContext('${a.key}').
|
|
591
|
+
`,
|
|
592
|
+
details: () => prose`
|
|
593
|
+
An island reads a context nothing in the browser provides. On a csr=false page a layout
|
|
594
|
+
or page runs only on the server, so a value it sets with Svelte's \`setContext\` never
|
|
595
|
+
reaches the island there. The island renders a different tree and Svelte throws its
|
|
596
|
+
server HTML away.
|
|
597
|
+
|
|
598
|
+
Provide the value with \`setContext\`, \`<Provide>\` or \`createContext\` imported from
|
|
599
|
+
\`ogygia\`. The island keeps reading it with \`getContext\`.
|
|
600
|
+
`
|
|
601
|
+
},
|
|
602
|
+
content_leaked_to_client: {
|
|
603
|
+
text: (a) => `content leaked into the CLIENT bundle: ${a.count} corpus module(s) (.svx/.md) shipped to the browser (in chunk '${a.chunk}').\n A content() collection was imported into client-shipped code — usually an island — which drags its eager import.meta.glob (every doc) in.\n Fix: keep the collection in a server-only module (or a .remote.ts) and feed islands DATA (refs) via props or a remote, never the collection itself.\n` + a.modules.split("\n").map((m) => " " + m).join("\n") + (a.count > 5 ? "\n …" : ""),
|
|
604
|
+
details: () => prose`
|
|
605
|
+
Documents of a content collection ended up in the browser bundle. A collection imports
|
|
606
|
+
every document it holds, so importing it into an island ships all of them.
|
|
607
|
+
|
|
608
|
+
Keep the collection in server-only code (a \`+page.server.ts\`, a \`.remote.ts\`) and
|
|
609
|
+
pass islands the data they need, as props or from a remote function.
|
|
610
|
+
`
|
|
611
|
+
},
|
|
612
|
+
region_host_skipped: {
|
|
613
|
+
text: (a) => `regions: skipped ${a.file}: ${a.reason}${a.at ? ` at ${a.at}` : ""} — its region imports stay plain imports`,
|
|
614
|
+
details: () => prose`
|
|
615
|
+
ogygia could not parse the component, so its marked imports were left as plain imports:
|
|
616
|
+
no island, no hole. The Svelte compiler reports the parse error itself. Fix it and the
|
|
617
|
+
regions come back.
|
|
618
|
+
`
|
|
619
|
+
},
|
|
620
|
+
hole_wake_deprecated: {
|
|
621
|
+
text: (a) => prose`
|
|
622
|
+
${a.host}: ${a.said ? `${a.said} times a \`${a.render_key}: 'deferred'\` hole with` : `a \`${a.render_key}: 'deferred'\` hole timed with`} \`${a.wake_key}: '${a.value}'\`, which is deprecated. Write \`${a.render_key}:
|
|
623
|
+
'deferred', ${a.fetch_key}: '${a.value}'\` instead: \`${a.fetch_key}\` says when a hole's
|
|
624
|
+
HTML arrives. (\`${a.wake_key}\` is when an island's JS runs; a hole ships no JS.)
|
|
625
|
+
`,
|
|
626
|
+
details: () => prose`
|
|
627
|
+
A deferred region (a hole) is timed with \`wake\`. \`wake\` is when an island's
|
|
628
|
+
JavaScript runs, and a hole ships none: its timing is \`fetch\`, when its HTML arrives.
|
|
629
|
+
The old spelling still works for now. Write \`render: 'deferred', fetch: 'visible'\`.
|
|
630
|
+
`
|
|
631
|
+
},
|
|
632
|
+
snippet_store_snapshot: {
|
|
633
|
+
text: (a) => prose`
|
|
634
|
+
${a.host}: {#snippet ${a.snippet}} crosses an island boundary and reads \`${a.store}\`
|
|
635
|
+
(at ${a.at}) — captured as a FROZEN snapshot of the store's value at render time; later
|
|
636
|
+
store updates never reach the island. To make the snapshot explicit (and silence this),
|
|
637
|
+
read it at host scope outside the snippet — e.g. \`const ${a.store.slice(1)}_value =
|
|
638
|
+
${a.store};\` — and use that.
|
|
639
|
+
`,
|
|
640
|
+
details: () => prose`
|
|
641
|
+
A snippet passed into an island reads a store with \`$\`. In plain Svelte that value is
|
|
642
|
+
live. Across an island boundary the snippet is rendered once from the values it captured,
|
|
643
|
+
so the island keeps the value the store had at render time.
|
|
644
|
+
|
|
645
|
+
To say so in the code (and silence this), read the value into a host variable outside
|
|
646
|
+
the snippet and use that. For a value that keeps changing, share a wired class instead.
|
|
647
|
+
`
|
|
648
|
+
},
|
|
649
|
+
snippet_store_unverified: {
|
|
650
|
+
text: (a) => prose`
|
|
651
|
+
${a.host}: {#snippet ${a.snippet}} reads \`${a.store}\` (at ${a.at}), but
|
|
652
|
+
\`${a.store.slice(1)}\` is not a host declaration or import, so ogygia cannot verify it
|
|
653
|
+
is a store. Its value is captured at the host anyway — if the build now errors in
|
|
654
|
+
${a.host}, start there.
|
|
655
|
+
`,
|
|
656
|
+
details: () => prose`
|
|
657
|
+
A snippet passed into an island reads \`$name\`, but \`name\` is not declared or imported
|
|
658
|
+
in the host, so ogygia cannot tell it is a store. It captures the value at the host as if
|
|
659
|
+
it were. If the build then fails in that file, this is the place to look.
|
|
660
|
+
`
|
|
661
|
+
},
|
|
662
|
+
snippet_captures_store: {
|
|
663
|
+
text: (a) => prose`
|
|
664
|
+
${a.host}: {#snippet ${a.snippet}} crosses an island boundary and captures the store
|
|
665
|
+
\`${a.store}\` as an OBJECT — a host-declared store cannot cross (its functions don't
|
|
666
|
+
serialize). Use its value (\`$${a.store}\`) inside the snippet, or share live state with a
|
|
667
|
+
wired class instead.
|
|
668
|
+
`,
|
|
669
|
+
details: () => prose`
|
|
670
|
+
A snippet passed into an island uses a store declared in the host as an object. The
|
|
671
|
+
snippet's captures are serialized, and a store's functions cannot be. Read its value
|
|
672
|
+
with \`$\` inside the snippet, or share live state with a wired class.
|
|
673
|
+
`
|
|
674
|
+
},
|
|
675
|
+
barrels_component_skipped: {
|
|
676
|
+
text: (a) => `barrels: skipped ${a.file}: ${a.reason}${a.at ? ` at ${a.at}` : ""} — its imports stay on their barrels`,
|
|
677
|
+
details: () => prose`
|
|
678
|
+
ogygia rewrites imports from an index file (a barrel) to the files that define them, so
|
|
679
|
+
an island ships only what it uses. It could not parse this component, so its imports
|
|
680
|
+
stay as written and its island ships each barrel whole.
|
|
681
|
+
`
|
|
682
|
+
},
|
|
683
|
+
sass_missing: {
|
|
684
|
+
text: () => "a server-rendered component has `<style lang=\"scss\">` but neither `sass-embedded` nor `sass` is installed — its hole/router CSS ships unprocessed",
|
|
685
|
+
details: () => prose`
|
|
686
|
+
ogygia compiles the styles of components it serves itself (holes, router pages). One is
|
|
687
|
+
written in SCSS and no Sass compiler is installed, so its CSS ships as written. Install
|
|
688
|
+
\`sass-embedded\` or \`sass\`.
|
|
689
|
+
`
|
|
690
|
+
},
|
|
691
|
+
scss_compile_failed: {
|
|
692
|
+
text: (a) => `${a.file}: scss compile failed — ${a.reason}`,
|
|
693
|
+
details: () => prose`
|
|
694
|
+
A component's SCSS did not compile (\`reason\`), so its style block ships as written.
|
|
695
|
+
Fix the stylesheet.
|
|
696
|
+
`
|
|
697
|
+
},
|
|
698
|
+
ts_strip_failed: {
|
|
699
|
+
text: (a) => `${a.file}: TypeScript strip failed — ${a.reason}`,
|
|
700
|
+
details: () => prose`
|
|
701
|
+
ogygia strips the types from a component's TypeScript script to compile its styles, and
|
|
702
|
+
that failed (\`reason\`). The component's CSS may then ship unscoped. Fix the script.
|
|
703
|
+
`
|
|
704
|
+
},
|
|
705
|
+
optimize_deps_includes_ogygia: {
|
|
706
|
+
text: (a) => prose`
|
|
707
|
+
optimizeDeps.include lists ${a.specifiers}: ogygia must not be pre-bundled in dev (the
|
|
708
|
+
page would run two copies of its runtime, and islands with snippet props fail to
|
|
709
|
+
hydrate). Remove ${a.count === 1 ? "it" : "them"}.
|
|
710
|
+
`,
|
|
711
|
+
details: () => prose`
|
|
712
|
+
Vite's \`optimizeDeps.include\` lists part of ogygia. ogygia keeps itself out of Vite's
|
|
713
|
+
dependency pre-bundling, and listing it brings a second copy of its runtime into the dev
|
|
714
|
+
page. Remove those entries.
|
|
715
|
+
`
|
|
716
|
+
},
|
|
717
|
+
island_handoff_write_failed: {
|
|
718
|
+
text: () => "could not write the server-leg island handoff:",
|
|
719
|
+
details: () => prose`
|
|
720
|
+
The server build writes which components it transformed, so the client build emits only
|
|
721
|
+
the islands those pages place. Writing it failed (the error follows the message). The
|
|
722
|
+
build goes on and emits every island it found.
|
|
723
|
+
`
|
|
724
|
+
},
|
|
725
|
+
package_files_missing: {
|
|
726
|
+
text: (a) => `${a.package}: ogygia.files entry '${a.entry}' does not exist — skipped.`,
|
|
727
|
+
details: () => prose`
|
|
728
|
+
An \`ogygia.files\` entry in a dependency's \`package.json\` names a path that is not in
|
|
729
|
+
the package. It is skipped. The package should fix or remove the entry.
|
|
730
|
+
`
|
|
731
|
+
},
|
|
732
|
+
kit_config_unreadable: {
|
|
733
|
+
text: (a) => `could not read ${a.file} for kit.files.routes / kit.outDir — using the defaults (${a.routes}, ${a.out}). ${a.reason}`,
|
|
734
|
+
details: () => prose`
|
|
735
|
+
ogygia loads \`svelte.config.js\` to find the routes folder and Kit's output folder, and
|
|
736
|
+
loading it threw (the reason follows). It uses Kit's defaults. If the app moved either
|
|
737
|
+
folder, fix the config so it loads.
|
|
738
|
+
`
|
|
739
|
+
},
|
|
740
|
+
island_chunks_not_emitted: {
|
|
741
|
+
text: (a) => `${a.count} island chunk(s) not emitted: their host modules are not in the server bundle (unreachable from this build's routes).`,
|
|
742
|
+
details: () => prose`
|
|
743
|
+
The client build found islands whose host components no route of this build renders, so
|
|
744
|
+
it left their chunks out. Nothing is wrong unless an island is missing from a page that
|
|
745
|
+
should have it: then check the route that renders its host is part of the build.
|
|
746
|
+
`
|
|
747
|
+
},
|
|
748
|
+
flags_manifest_written: {
|
|
749
|
+
text: (a) => `flags manifest: ${a.count} flag(s) → node_modules/.ogygia/flags-manifest.json`,
|
|
750
|
+
details: () => prose`
|
|
751
|
+
The build wrote the inventory of every \`flag()\` it found, with where each is read, to
|
|
752
|
+
\`node_modules/.ogygia/flags-manifest.json\`. Tools (the devtools, a flag dashboard) read it
|
|
753
|
+
from there.
|
|
754
|
+
`
|
|
755
|
+
},
|
|
756
|
+
page_seed_report: {
|
|
757
|
+
text: (a) => `page seed: ${a.islands} island${a.islands === 1 ? "" : "s"} read page.data — ${a.pinned} pinned to ${a.keys} key${a.keys === 1 ? "" : "s"}, ${a.unpinned} ship all of it`,
|
|
758
|
+
details: () => prose`
|
|
759
|
+
An island that reads \`page.data\` gets a copy of it in the page. When the build can see
|
|
760
|
+
which keys it reads, the island is pinned to them and only those ship. When it cannot (the
|
|
761
|
+
whole object is spread, passed on, or read with a computed key), the island ships all of
|
|
762
|
+
\`page.data\`.
|
|
763
|
+
|
|
764
|
+
The lines below the report name the modules that made an island ship everything, with
|
|
765
|
+
the reason. Read the keys you need by name there, and the copy shrinks.
|
|
766
|
+
`
|
|
767
|
+
},
|
|
768
|
+
barrels_report: {
|
|
769
|
+
text: (a) => `barrels: ${a.importers} of ${a.files} files rewritten — ${a.imports} barrel imports → leaves (${a.names} names), ${a.barrels} barrels bypassed, ${a.seconds} s first to last transform`,
|
|
770
|
+
details: () => prose`
|
|
771
|
+
ogygia rewrote imports from index files (barrels) to the files that define each name, so
|
|
772
|
+
an island ships only what it uses. The report counts the rewrites and lists the barrels
|
|
773
|
+
that were bypassed the most, with how many files imported through each.
|
|
774
|
+
|
|
775
|
+
\`barrels: { report: 'all' }\` lists every barrel, \`report: false\` turns the report off,
|
|
776
|
+
and \`debug: true\` prints each rewrite as it happens.
|
|
777
|
+
`
|
|
778
|
+
},
|
|
779
|
+
barrels_report_none: {
|
|
780
|
+
text: (a) => `barrels: ${a.files} files scanned, no barrel imports to rewrite (${a.seconds} s)`,
|
|
781
|
+
details: () => prose`
|
|
782
|
+
ogygia looked for imports through index files (barrels) to rewrite to the files that
|
|
783
|
+
define each name, and found none. Nothing to do.
|
|
784
|
+
`
|
|
785
|
+
},
|
|
786
|
+
barrels_rewrite: {
|
|
787
|
+
text: (a) => `barrels: ${a.file}: ${a.names} ← ${a.barrel} → ${a.leaves}`,
|
|
788
|
+
details: () => prose`
|
|
789
|
+
With \`barrels: { debug: true }\`, ogygia prints each import it rewrites: the names,
|
|
790
|
+
the index file (barrel) they were imported through, and the files that define them,
|
|
791
|
+
which the import now points at.
|
|
792
|
+
`
|
|
793
|
+
}
|
|
794
|
+
};
|
|
795
|
+
const build = define_messages(BUILD_ERRORS, BUILD_WARNINGS);
|
|
796
|
+
const OgygiaError = build.OgygiaError;
|
|
797
|
+
const warn = build.warn;
|
|
798
|
+
/** A code's line as a string, for a logger that takes one (Rollup's `this.warn`). */
|
|
799
|
+
const line = build.line;
|
|
800
|
+
export { BUILD_ERRORS, BUILD_WARNINGS, OgygiaError, RETIRED_OPTIONS, line, warn };
|