@antelopejs/dms-frontend 0.9.1 → 0.9.3
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/README.md +9 -1
- package/dist/cancellation.js +2 -1
- package/dist/config.js +11 -7
- package/dist/derived-outputs.js +6 -113
- package/dist/dev-modules.js +3 -2
- package/dist/discovery.js +19 -12
- package/dist/fs-sync.js +1 -2
- package/dist/internal/guards.d.ts +5 -0
- package/dist/internal/guards.js +22 -0
- package/dist/internal/locale-catalogs.d.ts +6 -0
- package/dist/internal/locale-catalogs.js +115 -0
- package/dist/layer-aliases.js +2 -1
- package/dist/layers.js +2 -1
- package/dist/locale-files.js +9 -4
- package/dist/manifest-secrets.js +11 -4
- package/dist/manifest.js +11 -5
- package/dist/materialize.js +6 -5
- package/dist/module-set.js +2 -4
- package/dist/ports.js +8 -1
- package/dist/private-values.js +26 -17
- package/dist/project-modules.js +17 -11
- package/dist/renderer-range.js +2 -1
- package/dist/server-process.js +17 -16
- package/dist/update-check.js +23 -16
- package/dist/verify-source-runner.js +2 -2
- package/dist/workspace-setup.js +1 -2
- package/dist/workspace.js +11 -10
- package/package.json +7 -4
- package/skills/dms-frontend/SKILL.md +1 -1
- package/skills/dms-frontend/cases.json +77 -0
- package/templates/vue/app-runtime.ts +88 -7
- package/templates/vue/client-chunking.mjs +0 -5
- package/templates/vue/client-server-guard.mjs +10 -13
- package/templates/vue/entry-weight.mjs +12 -14
- package/templates/vue/frontend-module.ts +159 -3563
- package/templates/vue/frontend-runtime/async-data-entry.ts +320 -0
- package/templates/vue/frontend-runtime/async-data.ts +404 -0
- package/templates/vue/frontend-runtime/components.ts +386 -0
- package/templates/vue/frontend-runtime/cookies.ts +125 -0
- package/templates/vue/frontend-runtime/data-access.ts +132 -0
- package/templates/vue/frontend-runtime/dms-error.ts +11 -0
- package/templates/vue/frontend-runtime/errors.ts +145 -0
- package/templates/vue/frontend-runtime/fetch.ts +306 -0
- package/templates/vue/frontend-runtime/module-registration.ts +247 -0
- package/templates/vue/frontend-runtime/paged-data.ts +191 -0
- package/templates/vue/frontend-runtime/payload.ts +172 -0
- package/templates/vue/frontend-runtime/route.ts +328 -0
- package/templates/vue/frontend-runtime/sdk.ts +300 -0
- package/templates/vue/frontend-runtime/state.ts +167 -0
- package/templates/vue/frontend-runtime/types.ts +361 -0
- package/templates/vue/frontend-runtime/ui.ts +247 -0
- package/templates/vue/globals.d.ts +5 -0
- package/templates/vue/head-order.mjs +11 -13
- package/templates/vue/icon-bundle.ts +31 -0
- package/templates/vue/message-subset.ts +65 -0
- package/templates/vue/network-error.ts +4 -0
- package/templates/vue/prepare-types.mjs +0 -8
- package/templates/vue/server/auth/backend.mjs +4 -2
- package/templates/vue/server/auth/establish-endpoints.mjs +14 -9
- package/templates/vue/server/auth/session.mjs +4 -3
- package/templates/vue/server/auth-hooks.mjs +6 -6
- package/templates/vue/server/backend-proxies.mjs +6 -6
- package/templates/vue/server/backend-response.mjs +15 -14
- package/templates/vue/server/built-files.mjs +10 -8
- package/templates/vue/server/cli-report.mjs +7 -5
- package/templates/vue/server/client-error.mjs +11 -8
- package/templates/vue/server/client-manifest.mjs +9 -8
- package/templates/vue/server/content.mjs +2 -1
- package/templates/vue/server/dev-private-files.mjs +20 -15
- package/templates/vue/server/dev-styles.mjs +22 -25
- package/templates/vue/server/email-bundle-watch.mjs +0 -12
- package/templates/vue/server/email.mjs +20 -15
- package/templates/vue/server/favicon.mjs +12 -11
- package/templates/vue/server/homepage.mjs +8 -10
- package/templates/vue/server/icons.mjs +18 -9
- package/templates/vue/server/in-place-render.mjs +6 -8
- package/templates/vue/server/listen-host.mjs +2 -2
- package/templates/vue/server/module-event.mjs +5 -5
- package/templates/vue/server/module-routes.mjs +11 -7
- package/templates/vue/server/module-server.mjs +8 -7
- package/templates/vue/server/module-testing.mjs +7 -7
- package/templates/vue/server/page-props.mjs +14 -14
- package/templates/vue/server/path-patterns.mjs +4 -4
- package/templates/vue/server/proxy-compression.mjs +21 -13
- package/templates/vue/server/proxy-headers.mjs +5 -3
- package/templates/vue/server/proxy-redirects.mjs +7 -6
- package/templates/vue/server/proxy-transfers.mjs +15 -11
- package/templates/vue/server/public-endpoints.mjs +27 -19
- package/templates/vue/server/public-options.mjs +9 -7
- package/templates/vue/server/request-failure.mjs +4 -6
- package/templates/vue/server/request-routing.mjs +8 -11
- package/templates/vue/server/request-target.mjs +6 -6
- package/templates/vue/server/route-rules.mjs +7 -5
- package/templates/vue/server/static-files.mjs +19 -10
- package/templates/vue/server/web-body.mjs +3 -4
- package/templates/vue/server.mjs +32 -19
- package/templates/vue/sfc-global-types.mjs +27 -24
- package/templates/vue/ssr-renderer.ts +10 -1
- package/templates/vue/ui-inertia-page.mjs +7 -7
- package/templates/vue/ui-kbd.mjs +10 -10
- package/templates/vue/ui-lazy-icons.mjs +44 -0
- package/templates/vue/ui-request-state.mjs +9 -9
- package/templates/vue/vite.config.ts +2 -0
|
@@ -4,6 +4,7 @@ import { useToast } from "@nuxt/ui/composables/useToast";
|
|
|
4
4
|
import { useAppConfig } from "@nuxt/ui/runtime/vue/composables/useAppConfig";
|
|
5
5
|
import { en as uiEn, fr as uiFr } from "@nuxt/ui/locale";
|
|
6
6
|
import ui from "@nuxt/ui/vue-plugin";
|
|
7
|
+
import { router } from "@inertiajs/vue3";
|
|
7
8
|
import { useHead } from "@unhead/vue";
|
|
8
9
|
import type { VueHeadClient } from "@unhead/vue/types";
|
|
9
10
|
import type { IconifyIcon } from "@iconify/vue";
|
|
@@ -64,7 +65,13 @@ import {
|
|
|
64
65
|
supportedLocales,
|
|
65
66
|
syncLocaleMessages,
|
|
66
67
|
} from "./locales.generated";
|
|
67
|
-
import {
|
|
68
|
+
import {
|
|
69
|
+
type DmsMessageSubset,
|
|
70
|
+
SSR_MESSAGES_ID,
|
|
71
|
+
recordMessageReads,
|
|
72
|
+
} from "./message-subset";
|
|
73
|
+
import { NETWORK_ERROR_KEYS, showNetworkErrors } from "./network-error";
|
|
74
|
+
import { loadIconBundle } from "./icon-bundle";
|
|
68
75
|
import { createUiAppConfigMerger } from "./ui-app-config";
|
|
69
76
|
|
|
70
77
|
export interface DmsInertiaSetupProps {
|
|
@@ -86,8 +93,16 @@ export interface DmsAppOptions {
|
|
|
86
93
|
}
|
|
87
94
|
|
|
88
95
|
export interface DmsConfiguredApp {
|
|
89
|
-
/**
|
|
96
|
+
/**
|
|
97
|
+
* The locale of the catalog the app shows its messages from now, none when
|
|
98
|
+
* the page is served the messages it read alone.
|
|
99
|
+
*/
|
|
90
100
|
catalogLocale: () => string | undefined;
|
|
101
|
+
/**
|
|
102
|
+
* On the server, for a page of a visitor who is not signed in: the messages
|
|
103
|
+
* the render read, which the page carries instead of the whole catalog.
|
|
104
|
+
*/
|
|
105
|
+
messageSubset: () => DmsMessageSubset | undefined;
|
|
91
106
|
mounted: () => Promise<void>;
|
|
92
107
|
runtime: ReturnType<typeof createDmsFrontendRuntime>;
|
|
93
108
|
}
|
|
@@ -238,8 +253,18 @@ const DmsPersistentInertiaPage = Object.assign(DmsInertiaPage, {
|
|
|
238
253
|
layout: DmsPersistentLayout,
|
|
239
254
|
});
|
|
240
255
|
|
|
241
|
-
|
|
242
|
-
|
|
256
|
+
/**
|
|
257
|
+
* What a visit waits for before it shows its page, set when the first one
|
|
258
|
+
* starts from a page that began without what the pages after it read: a
|
|
259
|
+
* subset of the catalog, the icon bundle. Inertia also resolves the first page
|
|
260
|
+
* once the app is set up, which must not wait for it.
|
|
261
|
+
*/
|
|
262
|
+
let completeInitialAssets: (() => Promise<void>) | undefined;
|
|
263
|
+
|
|
264
|
+
export function resolveDmsInertiaPage(): Component | Promise<Component> {
|
|
265
|
+
return completeInitialAssets
|
|
266
|
+
? completeInitialAssets().then(() => DmsPersistentInertiaPage)
|
|
267
|
+
: DmsPersistentInertiaPage;
|
|
243
268
|
}
|
|
244
269
|
|
|
245
270
|
function renderDmsPage(
|
|
@@ -310,13 +335,66 @@ export async function configureDmsApp(
|
|
|
310
335
|
userLocale(options.initialPageProps.user) ??
|
|
311
336
|
readDmsLocaleCookie(runtime, supportedLocales) ??
|
|
312
337
|
DEFAULT_LOCALE;
|
|
313
|
-
const
|
|
338
|
+
const anonymous = !options.initialPageProps.user;
|
|
339
|
+
const subset = anonymous
|
|
340
|
+
? readServerRendered<DmsMessageSubset | undefined>(
|
|
341
|
+
SSR_MESSAGES_ID,
|
|
342
|
+
undefined,
|
|
343
|
+
)
|
|
344
|
+
: undefined;
|
|
345
|
+
const started = subset?.locale === locale ? subset : undefined;
|
|
346
|
+
const messages = started?.messages ?? (await loadLocaleMessages(locale));
|
|
347
|
+
const recorder =
|
|
348
|
+
anonymous && typeof window === "undefined"
|
|
349
|
+
? recordMessageReads(messages)
|
|
350
|
+
: undefined;
|
|
351
|
+
let loading: Promise<void> | undefined;
|
|
314
352
|
const i18n = createI18n({
|
|
315
353
|
legacy: false,
|
|
316
354
|
locale,
|
|
317
355
|
fallbackLocale: DEFAULT_LOCALE,
|
|
318
|
-
messages:
|
|
356
|
+
messages: started
|
|
357
|
+
? { [locale]: messages }
|
|
358
|
+
: { ...localeMessages, [locale]: recorder?.messages ?? messages },
|
|
359
|
+
...(started && {
|
|
360
|
+
missing: (_locale: string, key: string) => {
|
|
361
|
+
if (i18n.global.locale.value !== locale) return key;
|
|
362
|
+
void loadCompleteCatalog();
|
|
363
|
+
return "";
|
|
364
|
+
},
|
|
365
|
+
}),
|
|
319
366
|
});
|
|
367
|
+
function loadCompleteCatalog(): Promise<void> {
|
|
368
|
+
if (i18n.global.locale.value !== locale) return Promise.resolve();
|
|
369
|
+
loading ??= loadLocaleMessages(locale).then(
|
|
370
|
+
(complete) => {
|
|
371
|
+
i18n.global.setLocaleMessage(locale, complete);
|
|
372
|
+
i18n.global.setMissingHandler(null);
|
|
373
|
+
},
|
|
374
|
+
() => {
|
|
375
|
+
loading = undefined;
|
|
376
|
+
},
|
|
377
|
+
);
|
|
378
|
+
return loading;
|
|
379
|
+
}
|
|
380
|
+
if (anonymous && typeof window !== "undefined") {
|
|
381
|
+
const complete = async (): Promise<void> => {
|
|
382
|
+
await Promise.all([
|
|
383
|
+
started ? loadCompleteCatalog() : undefined,
|
|
384
|
+
loadIconBundle(),
|
|
385
|
+
]);
|
|
386
|
+
};
|
|
387
|
+
router.on("before", () => {
|
|
388
|
+
completeInitialAssets = complete;
|
|
389
|
+
void complete();
|
|
390
|
+
});
|
|
391
|
+
for (const type of ["pointerdown", "keydown", "focusin", "touchstart"])
|
|
392
|
+
addEventListener(type, () => void loadIconBundle(), {
|
|
393
|
+
once: true,
|
|
394
|
+
capture: true,
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
if (recorder) for (const key of NETWORK_ERROR_KEYS) i18n.global.te(key);
|
|
320
398
|
// A translation changed in a layer during development reaches the page
|
|
321
399
|
// without a reload. A server render imports the new catalogs instead.
|
|
322
400
|
if (typeof window !== "undefined") syncLocaleMessages(i18n.global);
|
|
@@ -339,6 +417,7 @@ export async function configureDmsApp(
|
|
|
339
417
|
// rendered: the page, its layout, and the components the render reached.
|
|
340
418
|
// Hydration then adopts the server-rendered markup instead of discarding it.
|
|
341
419
|
await Promise.all([
|
|
420
|
+
anonymous ? undefined : loadIconBundle(),
|
|
342
421
|
preloadDmsPage(options.initialPageProps),
|
|
343
422
|
resolveDmsAsyncComponents(
|
|
344
423
|
readServerRendered<string[]>(SSR_ASYNC_COMPONENTS_ID, []),
|
|
@@ -352,7 +431,9 @@ export async function configureDmsApp(
|
|
|
352
431
|
supportedLocales,
|
|
353
432
|
);
|
|
354
433
|
return {
|
|
355
|
-
catalogLocale: () =>
|
|
434
|
+
catalogLocale: () =>
|
|
435
|
+
recorder ? undefined : catalogLocale(i18n.global.locale.value),
|
|
436
|
+
messageSubset: () => recorder && { locale, messages: recorder.subset() },
|
|
356
437
|
mounted,
|
|
357
438
|
runtime,
|
|
358
439
|
};
|
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
// How the client bundle is cut into files, and what the build says about it.
|
|
2
|
-
//
|
|
3
|
-
// Kept beside vite.config.ts rather than inside it so the options can be
|
|
4
|
-
// exercised on their own, the way head-order.mjs and client-server-guard.mjs are.
|
|
5
|
-
|
|
6
1
|
/**
|
|
7
2
|
* Rolldown's `output.codeSplitting` for the client build.
|
|
8
3
|
*
|
|
@@ -1,16 +1,3 @@
|
|
|
1
|
-
// Keeping server code out of the browser.
|
|
2
|
-
//
|
|
3
|
-
// A module's `dms.server.ts` and the files under its `server/` directories run
|
|
4
|
-
// in the generated server only: they read private options, sign tokens, talk
|
|
5
|
-
// to the backend with its secrets. A client file that imports one of them,
|
|
6
|
-
// even statically and through an alias, would ship that code in the client
|
|
7
|
-
// bundle. Rollup's manifest only lists entries and dynamic imports, so a check
|
|
8
|
-
// on the built output misses a static import; the guard sits in the module
|
|
9
|
-
// graph instead, where every resolved file passes.
|
|
10
|
-
//
|
|
11
|
-
// Kept beside vite.config.ts rather than inside it so the plugin can be
|
|
12
|
-
// exercised on its own, the way head-order.mjs is.
|
|
13
|
-
|
|
14
1
|
import { relative, sep } from "node:path";
|
|
15
2
|
|
|
16
3
|
const SERVER_ENTRY = /(?:^|[\\/])dms\.server\.[cm]?[jt]sx?$/;
|
|
@@ -47,6 +34,16 @@ export function isServerSource(id, moduleRoots) {
|
|
|
47
34
|
* Fail a client build, and a client request in development, that loads server
|
|
48
35
|
* code. Server-side rendering and the server modules build load it through
|
|
49
36
|
* SSR, which the guard leaves alone.
|
|
37
|
+
*
|
|
38
|
+
* Keeps server code out of the browser. A module's `dms.server.ts` and the
|
|
39
|
+
* files under its `server/` directories run in the generated server only: they
|
|
40
|
+
* read private options, sign tokens, talk to the backend with its secrets. A
|
|
41
|
+
* client file that imports one of them, even statically and through an alias,
|
|
42
|
+
* would ship that code in the client bundle. Rollup's manifest only lists
|
|
43
|
+
* entries and dynamic imports, so a check on the built output misses a static
|
|
44
|
+
* import; the guard sits in the module graph instead, where every resolved file
|
|
45
|
+
* passes. Kept beside vite.config.ts rather than inside it so the plugin can be
|
|
46
|
+
* exercised on its own, the way head-order.mjs is.
|
|
50
47
|
*/
|
|
51
48
|
export function rejectServerSourcesInClient(moduleRoots) {
|
|
52
49
|
let ssrBuild = false;
|
|
@@ -1,15 +1,3 @@
|
|
|
1
|
-
// What each frontend module adds to the client entry.
|
|
2
|
-
//
|
|
3
|
-
// Every page loads the entry, and everything it imports statically, before it
|
|
4
|
-
// runs anything: a module's `dms.frontend.ts`, its plugins and whatever they
|
|
5
|
-
// import land there, on every page of every application that loads the
|
|
6
|
-
// module. The client build records, from the bundle's own metadata, how much
|
|
7
|
-
// of the entry each module's sources make up; `ajs dms build` reports it and
|
|
8
|
-
// warns about a module above its threshold.
|
|
9
|
-
//
|
|
10
|
-
// Kept beside vite.config.ts rather than inside it so the plugin can be
|
|
11
|
-
// exercised on its own, the way client-chunking.mjs is.
|
|
12
|
-
|
|
13
1
|
import { mkdirSync, writeFileSync } from "node:fs";
|
|
14
2
|
import { dirname, join, relative, sep } from "node:path";
|
|
15
3
|
|
|
@@ -109,6 +97,18 @@ export function attributeEntry(bundle, modules) {
|
|
|
109
97
|
* Records, in the client build, what each frontend module adds to the entry
|
|
110
98
|
* (`ENTRY_WEIGHT_FILE`). Server builds are left alone: their bundle is no
|
|
111
99
|
* page's entry.
|
|
100
|
+
*
|
|
101
|
+
* What each frontend module adds to the client entry. Every page loads the
|
|
102
|
+
* entry, and everything it imports statically, before it runs anything: a
|
|
103
|
+
* module's `dms.frontend.ts`, its plugins and whatever they import land there,
|
|
104
|
+
* on every page of every application that loads the module. The client build
|
|
105
|
+
* records, from the bundle's own metadata, how much of the entry each module's
|
|
106
|
+
* sources make up; `ajs dms build` reports it and warns about a module above
|
|
107
|
+
* its threshold. Kept beside vite.config.ts rather than inside it so the plugin
|
|
108
|
+
* can be exercised on its own, the way client-chunking.mjs is.
|
|
109
|
+
*
|
|
110
|
+
* The weight is recorded once the bundle is written: plugins that generate the
|
|
111
|
+
* bundle after this one still rewrite the chunks' code.
|
|
112
112
|
*/
|
|
113
113
|
export function recordEntryWeight(modules) {
|
|
114
114
|
let ssrBuild = false;
|
|
@@ -117,8 +117,6 @@ export function recordEntryWeight(modules) {
|
|
|
117
117
|
configResolved(config) {
|
|
118
118
|
ssrBuild = Boolean(config.build.ssr);
|
|
119
119
|
},
|
|
120
|
-
// Once the bundle is written: plugins that generate the bundle after this
|
|
121
|
-
// one still rewrite the chunks' code.
|
|
122
120
|
writeBundle(options, bundle) {
|
|
123
121
|
if (ssrBuild || !options.dir) return;
|
|
124
122
|
const file = join(options.dir, ENTRY_WEIGHT_FILE);
|