@olenbetong/appframe-vite 6.9.0 → 6.10.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/README.md CHANGED
@@ -83,8 +83,11 @@ build then leaves `react`, `react/jsx-runtime`, `react/jsx-dev-runtime`, `react-
83
83
  which the template's import map resolves to `@olenbetong/synergi-platform` — one cached React
84
84
  per page, shared with the site chrome. The `af.data` global redirect (`dataGlobal`) then only
85
85
  applies to the dev server, which has no import map. The build also writes `dist/platform.json`
86
- with the versions the app compiled against; `scripts/app-deploy.ts` refuses to deploy when the
87
- target article renders no import map or its platform carries other versions (override with
86
+ with the platform version the app was built alongside (the workspace's
87
+ `packages/synergi-platform`) and the versions it compiled against; `scripts/app-deploy.ts` pins
88
+ the article to that platform version (its `PlatformHead` and `PlatformStyles` blocks) and
89
+ refuses to deploy when the article is not on a 2026 template, that version is not served on the
90
+ target site, or its manifest carries other versions than the app (override with
88
91
  `--allow-platform-mismatch`).
89
92
 
90
93
  ## What it does (at a glance)
package/lib/build.d.ts CHANGED
@@ -22,14 +22,20 @@ export declare function usesPlatform(appframe: {
22
22
  */
23
23
  export declare const PLATFORM_UPSTREAM: string[];
24
24
  export type PlatformManifest = {
25
+ /**
26
+ * The `@olenbetong/synergi-platform` version the app was built alongside - the one its
27
+ * article is pinned to on deploy. Missing when the build found no platform package.
28
+ */
29
+ platform?: string;
25
30
  /** The package versions the app resolved at build time. */
26
31
  upstream: Record<string, string>;
27
32
  };
28
33
  /**
29
- * Writes `dist/platform.json` after a platform build: the versions of the platform packages the
30
- * app was compiled against. The deploy script compares it with the manifest of the platform the
31
- * target site serves, since an app compiled against one React and run on another is a runtime
32
- * error, not a build error.
34
+ * Writes `dist/platform.json` after a platform build: the platform version the app was built
35
+ * alongside and the versions of the platform packages it compiled against. The deploy pins the
36
+ * article to that platform version (its `PlatformHead` block) and compares the versions with the
37
+ * manifest that version serves on the target site, since an app compiled against one React and
38
+ * run on another is a runtime error, not a build error.
33
39
  */
34
40
  export declare function platformManifest(): Plugin;
35
41
  export declare function addAppframeBuildConfig(config: UserConfig): Promise<UserConfig>;
package/lib/build.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { existsSync } from "node:fs";
2
2
  import { readFile, writeFile } from "node:fs/promises";
3
- import { resolve } from "node:path";
3
+ import { dirname, resolve } from "node:path";
4
4
  import { visualizer } from "rollup-plugin-visualizer";
5
5
  import { esmExternalRequirePlugin } from "vite";
6
6
  import { importJson } from "./importJson.js";
@@ -70,17 +70,47 @@ export const PLATFORM_UPSTREAM = [
70
70
  "@olenbetong/appframe-ds",
71
71
  ];
72
72
  /**
73
- * Writes `dist/platform.json` after a platform build: the versions of the platform packages the
74
- * app was compiled against. The deploy script compares it with the manifest of the platform the
75
- * target site serves, since an app compiled against one React and run on another is a runtime
76
- * error, not a build error.
73
+ * The platform package's version as the app sees it: its own copy under node_modules when it
74
+ * depends on `@olenbetong/synergi-platform`, otherwise the workspace's `packages/synergi-platform`
75
+ * found by walking up from the app - every app lives in the monorepo next to it.
76
+ */
77
+ async function platformVersion(cwd) {
78
+ let candidates = [resolve(cwd, "node_modules", "@olenbetong", "synergi-platform", "package.json")];
79
+ let dir = cwd;
80
+ while (true) {
81
+ candidates.push(resolve(dir, "packages", "synergi-platform", "package.json"));
82
+ let parent = dirname(dir);
83
+ if (parent === dir)
84
+ break;
85
+ dir = parent;
86
+ }
87
+ for (let file of candidates) {
88
+ try {
89
+ return JSON.parse(await readFile(file, "utf8")).version;
90
+ }
91
+ catch {
92
+ // Not here; try the next candidate.
93
+ }
94
+ }
95
+ return undefined;
96
+ }
97
+ /**
98
+ * Writes `dist/platform.json` after a platform build: the platform version the app was built
99
+ * alongside and the versions of the platform packages it compiled against. The deploy pins the
100
+ * article to that platform version (its `PlatformHead` block) and compares the versions with the
101
+ * manifest that version serves on the target site, since an app compiled against one React and
102
+ * run on another is a runtime error, not a build error.
77
103
  */
78
104
  export function platformManifest() {
79
105
  return {
80
106
  name: "appframe:platform-manifest",
81
107
  apply: "build",
82
108
  async writeBundle() {
83
- let manifest = { upstream: {} };
109
+ let manifest = { platform: await platformVersion(process.cwd()), upstream: {} };
110
+ if (manifest.platform === undefined) {
111
+ delete manifest.platform;
112
+ this.warn("No @olenbetong/synergi-platform package found; dist/platform.json records no platform version and the app cannot be deployed to a platform article.");
113
+ }
84
114
  for (let name of PLATFORM_UPSTREAM) {
85
115
  let file = resolve(process.cwd(), "node_modules", name, "package.json");
86
116
  try {
package/lib/index.js CHANGED
@@ -22,19 +22,27 @@ let lastHostname;
22
22
  let watcher;
23
23
  let resourcesWatcher = null;
24
24
  let resourcesDebounce = null;
25
- try {
26
- let appPkgUrl = `file://${process.cwd()}/package.json`;
27
- watcher = watch(appPkgUrl).on("all", async () => {
28
- if (server) {
29
- let { hostname } = await getLoginInfo();
30
- if (lastHostname !== hostname) {
31
- server.restart(false);
25
+ /**
26
+ * Restarts the dev server when the app's package.json changes its hostname. Started with the
27
+ * dev server, never at import: a watcher keeps node alive, and the deploy and release scripts
28
+ * import this package for its exports without ever running a server.
29
+ */
30
+ function watchAppPackage() {
31
+ watcher?.close();
32
+ try {
33
+ let appPkgUrl = `file://${process.cwd()}/package.json`;
34
+ watcher = watch(appPkgUrl).on("all", async () => {
35
+ if (server) {
36
+ let { hostname } = await getLoginInfo();
37
+ if (lastHostname !== hostname) {
38
+ server.restart(false);
39
+ }
32
40
  }
33
- }
34
- });
35
- }
36
- catch (error) {
37
- console.log(createLogMessage(`failed to watch package.json: ${error.message}`, { type: "warn" }));
41
+ });
42
+ }
43
+ catch (error) {
44
+ console.log(createLogMessage(`failed to watch package.json: ${error.message}`, { type: "warn" }));
45
+ }
38
46
  }
39
47
  const jsonParser = bodyParser.json();
40
48
  export default function appframe(options = {}) {
@@ -121,10 +129,10 @@ export default function appframe(options = {}) {
121
129
  },
122
130
  };
123
131
  if (command === "build") {
124
- watcher.close();
125
132
  await addAppframeBuildConfig(config);
126
133
  }
127
134
  else {
135
+ watchAppPackage();
128
136
  let proxy = config.server?.proxy ?? {};
129
137
  let routes = getProxyRoutes();
130
138
  let { hostname, username, password } = await getLoginInfo();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@olenbetong/appframe-vite",
3
- "version": "6.9.0",
3
+ "version": "6.10.0",
4
4
  "description": "Tools to use and deploy Vite applications to Appframe",
5
5
  "main": "./lib/index.js",
6
6
  "type": "module",