@vmz/core 0.1.30 → 0.1.32

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.
@@ -56,7 +56,7 @@ export function installClientNavigation(opts = {}) {
56
56
  win.vmzDestroy(inst);
57
57
  }
58
58
  async function loadDomFallback() {
59
- return import(/* @vite-ignore */ '/vmz-dom.js');
59
+ return import(/* @vite-ignore */ '/dom.browser.js');
60
60
  }
61
61
  function navKey(pathname, search) {
62
62
  return `${pathname || '/'}${search || ''}`;
@@ -173,11 +173,11 @@ export declare const directApi: {
173
173
  /**
174
174
  * Nested component (sync Direct child or island schedule).
175
175
  * @param {object} hostInst
176
- * @param {string} name
176
+ * @param {string | Function} nameOrCtor — PascalCase tag string, or static Ctor import
177
177
  * @param {Record<string, any>} props
178
178
  * @param {string | null} client
179
179
  */
180
- component(hostInst: any, name: any, props: any, client: any): any;
180
+ component(hostInst: any, nameOrCtor: any, props: any, client: any): any;
181
181
  /**
182
182
  * Subscribe to a child component event (`@submit` → event name `submit`).
183
183
  * Orthogonal to function props (`:on-submit` → prop `onSubmit`).
package/dist/dom-core.js CHANGED
@@ -537,11 +537,12 @@ export const directApi = {
537
537
  /**
538
538
  * Nested component (sync Direct child or island schedule).
539
539
  * @param {object} hostInst
540
- * @param {string} name
540
+ * @param {string | Function} nameOrCtor — PascalCase tag string, or static Ctor import
541
541
  * @param {Record<string, any>} props
542
542
  * @param {string | null} client
543
543
  */
544
- component(hostInst, name, props, client) {
544
+ component(hostInst, nameOrCtor, props, client) {
545
+ const name = typeof nameOrCtor === 'function' ? nameOrCtor.__vmzTag || nameOrCtor.name || 'Component' : nameOrCtor;
545
546
  /** @type {HTMLElement | null} */
546
547
  let host = null;
547
548
  if (directApi._resumeAdopt && typeof directApi._resumeAdopt.componentHost === 'function') {
@@ -574,7 +575,7 @@ export const directApi = {
574
575
  }
575
576
  // resume: resume on schedule; EventEntry may lazy-load chunk via __vmzLoadComponent.
576
577
  scheduleClientOn(host, String(client), async () => {
577
- const Ctor = await resolveComponent(name);
578
+ const Ctor = typeof nameOrCtor === 'function' ? nameOrCtor : await resolveComponent(name);
578
579
  if (!Ctor) {
579
580
  // Replace placeholder island with leaf error node (do not throw page).
580
581
  const err = createUnknownComponentElement(name, 'island');
@@ -585,7 +586,8 @@ export const directApi = {
585
586
  });
586
587
  return host;
587
588
  }
588
- const Ctor = components[name];
589
+ // Static Ctor import path: use Function directly (no registry lookup).
590
+ const Ctor = typeof nameOrCtor === 'function' ? nameOrCtor : components[name];
589
591
  if (!Ctor) {
590
592
  return createUnknownComponentElement(name, 'client');
591
593
  }
package/dist/dom-ssr.js CHANGED
@@ -755,8 +755,9 @@ const serializeApi = {
755
755
  }
756
756
  return frag;
757
757
  },
758
- component(hostInst, name, props, client) {
759
- const Ctor = getRegisteredComponent(name);
758
+ component(hostInst, nameOrCtor, props, client) {
759
+ const name = typeof nameOrCtor === 'function' ? nameOrCtor.__vmzTag || nameOrCtor.name || 'Component' : nameOrCtor;
760
+ const Ctor = typeof nameOrCtor === 'function' ? nameOrCtor : getRegisteredComponent(name);
760
761
  if (!Ctor) {
761
762
  return serializeUnknownComponentNode(name);
762
763
  }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Browser delivery face (0.1.31): DOM core + hydrate/resume/route attach.
3
+ * Does NOT re-export Node SSR `renderToString` / `renderToStream`.
4
+ * Full barrel remains `@vmz/core/dom` (`dom.js` / dist `vmz-dom.js`) for Node host.
5
+ */
6
+ export * from './dom-core.js';
7
+ export { attachEventEntries, hydrate, hydrateIslands, hydrateRoute, hydrateRoutePage, resume, resumeIslands, } from './dom-ssr.js';
@@ -0,0 +1,8 @@
1
+ // @ts-nocheck
2
+ /**
3
+ * Browser delivery face (0.1.31): DOM core + hydrate/resume/route attach.
4
+ * Does NOT re-export Node SSR `renderToString` / `renderToStream`.
5
+ * Full barrel remains `@vmz/core/dom` (`dom.js` / dist `vmz-dom.js`) for Node host.
6
+ */
7
+ export * from './dom-core.js';
8
+ export { attachEventEntries, hydrate, hydrateIslands, hydrateRoute, hydrateRoutePage, resume, resumeIslands, } from './dom-ssr.js';
@@ -32,7 +32,19 @@ const ROUTE_CATALOG_SCHEMA = 'vmz.route.catalog.v0';
32
32
  const ROUTE_CATALOG_REL = '_vmz/route-catalog.json';
33
33
  const LOCALE_LINK_PLAN_REL = '_vmz/locale-link-plan.json';
34
34
  const require = createRequire(import.meta.url);
35
- const distDir = process.env.VMZ_DIST ? path.resolve(process.env.VMZ_DIST) : path.dirname(fileURLToPath(import.meta.url));
35
+ /** App delivery root. Host companions may live under `_vmz/host/` (0.1.31). */
36
+ function resolveServeDistDir() {
37
+ if (process.env.VMZ_DIST)
38
+ return path.resolve(process.env.VMZ_DIST);
39
+ const here = path.dirname(fileURLToPath(import.meta.url));
40
+ const norm = here.replace(/\\/g, '/');
41
+ const marker = '/_vmz/host';
42
+ const idx = norm.toLowerCase().lastIndexOf(marker);
43
+ if (idx >= 0)
44
+ return path.resolve(here.slice(0, idx));
45
+ return here;
46
+ }
47
+ const distDir = resolveServeDistDir();
36
48
  /** App project root for bare import / JSON resolve (dev SSR ≡ build node_modules). */
37
49
  function projectRootForResolve() {
38
50
  const fromEnv = typeof process.env.VMZ_PROJECT_ROOT === 'string' ? process.env.VMZ_PROJECT_ROOT.trim() : '';
@@ -510,26 +522,11 @@ async function* emitPageHtml(Page, chunkId, eventOnlyShell, props = {}, opts = {
510
522
  hideOverlay();
511
523
  if (msg.mode === "island") {
512
524
  try {
513
- const { registerComponents, hydrate } = await import("/vmz-dom.js?t=" + msg.token);
514
- const names = (msg.affectedChunks || [])
515
- .map((c) => String(c))
516
- .filter((c) => c.startsWith("components/") || !c.includes("/"))
517
- .map((c) => c.split("/").pop())
518
- .filter(Boolean);
519
- const map = {};
520
- for (const name of names) {
521
- let mod;
522
- try {
523
- mod = await import("/components/" + name + ".client.js?t=" + msg.token);
524
- } catch {
525
- mod = await import("/" + name + ".client.js?t=" + msg.token);
526
- }
527
- map[name] = mod.default;
528
- }
529
- if (Object.keys(map).length) registerComponents(map);
525
+ const { hydrate } = await import("/dom.browser.js?t=" + msg.token);
530
526
  const root = document.getElementById("app");
531
527
  const pageChunk = root && root.getAttribute("data-vmz-page");
532
528
  if (root && pageChunk) {
529
+ // Child Ctors come from page static imports after reload with cache token.
533
530
  const pageMod = await import("/" + pageChunk + ".client.js?t=" + msg.token);
534
531
  let hmrProps = {};
535
532
  try {
@@ -799,7 +796,6 @@ async function softReload(opts = {}) {
799
796
  reloadToken = nextToken;
800
797
  const affected = opts.payload?.affectedChunks ?? [];
801
798
  const seeds = opts.payload?.seedChunks ?? [];
802
- const emitted = opts.payload?.emitted ?? [];
803
799
  const full = opts.payload?.full;
804
800
  const islandHmr = Boolean(opts.payload?.islandHmr);
805
801
  const rerunLoaders = opts.payload?.rerunLoaders ?? [];
@@ -809,7 +805,8 @@ async function softReload(opts = {}) {
809
805
  const bundleRevision = opts.payload?.bundleRevision != null ? String(opts.payload.bundleRevision) : null;
810
806
  if (buildId)
811
807
  lastDevBuildId = buildId;
812
- const reloadAllPages = shouldReloadAllPages({ full, affected, emitted, islandHmr, rerunLoaders });
808
+ // 0.1.31: payload-only scope. `reloadToken` is opaque cache-bust — never invent full/affected here.
809
+ const reloadAllPages = Boolean(full) || (!islandHmr && rerunLoaders.length === 0 && affected.length === 0);
813
810
  try {
814
811
  try {
815
812
  const routes = JSON.parse(await readFile(path.join(distDir, 'vmz-routes.json'), 'utf8'));
@@ -940,28 +937,6 @@ async function softReload(opts = {}) {
940
937
  throw err;
941
938
  }
942
939
  }
943
- /**
944
- * Shared lib / full rebuild / missing affected list → refresh every page ctor.
945
- * Otherwise only re-import the dirty page chunks (Vite-like module graph).
946
- * @param {{ full?: boolean, affected: string[], emitted: string[], islandHmr: boolean }} opts
947
- */
948
- function shouldReloadAllPages(opts) {
949
- if (opts.islandHmr)
950
- return false;
951
- if (opts.full)
952
- return true;
953
- if (Array.isArray(opts.rerunLoaders) && opts.rerunLoaders.length > 0)
954
- return false;
955
- if (!opts.affected.length)
956
- return true;
957
- for (const f of opts.emitted) {
958
- const n = String(f).replace(/\\/g, '/');
959
- if (n.includes('/lib/') || /\/Application\.client\.js$/.test(n) || /\/vmz-(dom|runtime|http|client-nav)\.js$/.test(n)) {
960
- return true;
961
- }
962
- }
963
- return false;
964
- }
965
940
  /** @param {string} chunkId @param {string[]} affected */
966
941
  function pageNeedsReload(chunkId, affected) {
967
942
  if (chunkId === 'pages/Layout' || chunkId.endsWith('/Layout'))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vmz/core",
3
- "version": "0.1.30",
3
+ "version": "0.1.32",
4
4
  "type": "module",
5
5
  "description": "VMZ production runtime core — DOM / SSR / HTTP / WriteBarrier (no compiler)",
6
6
  "exports": {
@@ -16,6 +16,10 @@
16
16
  "types": "./dist/dom.client.d.ts",
17
17
  "default": "./dist/dom.client.js"
18
18
  },
19
+ "./dom/browser": {
20
+ "types": "./dist/dom.browser.d.ts",
21
+ "default": "./dist/dom.browser.js"
22
+ },
19
23
  "./server": {
20
24
  "types": "./dist/server.d.ts",
21
25
  "default": "./dist/server.js"
@@ -66,12 +70,12 @@
66
70
  "linkedom": "^0.18.13"
67
71
  },
68
72
  "optionalDependencies": {
69
- "@vmz/vmz-win32-x64": "0.1.30",
70
- "@vmz/vmz-win32-arm64": "0.1.30",
71
- "@vmz/vmz-darwin-x64": "0.1.30",
72
- "@vmz/vmz-darwin-arm64": "0.1.30",
73
- "@vmz/vmz-linux-x64": "0.1.30",
74
- "@vmz/vmz-linux-arm64": "0.1.30"
73
+ "@vmz/vmz-win32-x64": "0.1.32",
74
+ "@vmz/vmz-win32-arm64": "0.1.32",
75
+ "@vmz/vmz-darwin-x64": "0.1.32",
76
+ "@vmz/vmz-darwin-arm64": "0.1.32",
77
+ "@vmz/vmz-linux-x64": "0.1.32",
78
+ "@vmz/vmz-linux-arm64": "0.1.32"
75
79
  },
76
80
  "publishConfig": {
77
81
  "access": "public"