@lowdefy/server-dev 4.7.0 → 4.7.1
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/lib/client/Page.js +12 -0
- package/lib/client/utils/usePageConfig.js +18 -3
- package/lib/server/jitPageBuilder.js +19 -0
- package/package.json +29 -29
- package/package.original.json +29 -29
- package/pages/api/icons/dynamic.js +34 -0
package/lib/client/Page.js
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
import React from 'react';
|
|
18
|
+
import { GenIcon } from 'react-icons/lib';
|
|
18
19
|
import Client from '@lowdefy/client';
|
|
19
20
|
|
|
20
21
|
import BuildErrorPage from './BuildErrorPage.js';
|
|
@@ -58,6 +59,17 @@ const Page = ({
|
|
|
58
59
|
// Merge dynamic JS entries fetched after JIT build with the static jsMap
|
|
59
60
|
const mergedJsMap = pageConfig._jsEntries ? { ...jsMap, ...pageConfig._jsEntries } : jsMap;
|
|
60
61
|
|
|
62
|
+
// Merge JIT-discovered icon data into the static icons object.
|
|
63
|
+
// createIcon.js looks up Icons[name] on every render from the captured reference,
|
|
64
|
+
// so mutating the original object makes new icons available immediately.
|
|
65
|
+
if (pageConfig._dynamicIcons) {
|
|
66
|
+
for (const [name, data] of Object.entries(pageConfig._dynamicIcons)) {
|
|
67
|
+
if (!types.icons[name]) {
|
|
68
|
+
types.icons[name] = GenIcon(data);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
61
73
|
return (
|
|
62
74
|
<Client
|
|
63
75
|
auth={auth}
|
|
@@ -32,6 +32,16 @@ async function fetchJsEntries(basePath) {
|
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
async function fetchDynamicIcons(basePath) {
|
|
36
|
+
try {
|
|
37
|
+
const res = await fetch(`${basePath}/api/icons/dynamic`);
|
|
38
|
+
if (!res.ok) return {};
|
|
39
|
+
return parseJsModule(await res.text());
|
|
40
|
+
} catch {
|
|
41
|
+
return {};
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
35
45
|
async function fetchPageConfig(url) {
|
|
36
46
|
const res = await fetch(url, {
|
|
37
47
|
headers: { 'Content-Type': 'application/json' },
|
|
@@ -50,11 +60,16 @@ async function fetchPageConfig(url) {
|
|
|
50
60
|
throw new Error(data.message || 'Request error');
|
|
51
61
|
}
|
|
52
62
|
|
|
53
|
-
// Fetch jsMap after page build completes
|
|
54
|
-
//
|
|
63
|
+
// Fetch jsMap and dynamic icons after page build completes
|
|
64
|
+
// (JIT build may have added new entries).
|
|
65
|
+
// Extract basePath from the URL to construct the endpoints.
|
|
55
66
|
const basePath = url.replace(/\/api\/page\/.*$/, '');
|
|
56
|
-
const jsEntries = await
|
|
67
|
+
const [jsEntries, dynamicIcons] = await Promise.all([
|
|
68
|
+
fetchJsEntries(basePath),
|
|
69
|
+
fetchDynamicIcons(basePath),
|
|
70
|
+
]);
|
|
57
71
|
data._jsEntries = jsEntries;
|
|
72
|
+
data._dynamicIcons = dynamicIcons;
|
|
58
73
|
|
|
59
74
|
return data;
|
|
60
75
|
}
|
|
@@ -34,6 +34,12 @@ let cachedRegistry = null;
|
|
|
34
34
|
let cachedBuildContext = null;
|
|
35
35
|
let lastInvalidationMtime = null;
|
|
36
36
|
|
|
37
|
+
// Frozen snapshot of icon imports from the initial build (what's actually in the Next.js bundle).
|
|
38
|
+
// Module-level so it persists across context resets (skeleton rebuilds update iconImports.json
|
|
39
|
+
// with newly discovered icons, but those aren't in the bundle until the next nextBuild).
|
|
40
|
+
// Only resets when the server process restarts (which happens after every nextBuild).
|
|
41
|
+
let bundledIconImports = null;
|
|
42
|
+
|
|
37
43
|
function readJsonFile(filePath) {
|
|
38
44
|
try {
|
|
39
45
|
const content = fs.readFileSync(filePath, 'utf8');
|
|
@@ -112,6 +118,19 @@ function getBuildContext(buildDirectory, configDirectory) {
|
|
|
112
118
|
readJsonFile(path.join(buildDirectory, 'installedPluginPackages.json')) ?? [];
|
|
113
119
|
cachedBuildContext.installedPluginPackages = new Set(installedPluginPackages);
|
|
114
120
|
|
|
121
|
+
// Use the frozen icon imports from the initial build for JIT detection.
|
|
122
|
+
// This represents what's actually in the Next.js bundle — not what shallowBuild
|
|
123
|
+
// discovers on subsequent rebuilds (those icons aren't bundled yet).
|
|
124
|
+
// bundledIconImports is module-level and only resets on server restart (after nextBuild).
|
|
125
|
+
if (!bundledIconImports) {
|
|
126
|
+
bundledIconImports = readJsonFile(path.join(buildDirectory, 'iconImports.json')) ?? [];
|
|
127
|
+
}
|
|
128
|
+
cachedBuildContext.iconImports = bundledIconImports;
|
|
129
|
+
|
|
130
|
+
// Accumulator for dynamically extracted icon SVG data written to plugins/iconsDynamic.js.
|
|
131
|
+
// Reset on skeleton rebuild (cachedBuildContext = null) — JIT re-discovers as needed.
|
|
132
|
+
cachedBuildContext.dynamicIconData = {};
|
|
133
|
+
|
|
115
134
|
// Advance makeId past all skeleton IDs to prevent collisions with JIT builds
|
|
116
135
|
const idCounter = readJsonFile(path.join(buildDirectory, 'idCounter.json'));
|
|
117
136
|
if (idCounter != null) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lowdefy/server-dev",
|
|
3
|
-
"version": "4.7.
|
|
3
|
+
"version": "4.7.1",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"description": "",
|
|
6
6
|
"homepage": "https://lowdefy.com",
|
|
@@ -36,34 +36,34 @@
|
|
|
36
36
|
".npmrc"
|
|
37
37
|
],
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@lowdefy/actions-core": "4.7.
|
|
40
|
-
"@lowdefy/api": "4.7.
|
|
41
|
-
"@lowdefy/block-utils": "4.7.
|
|
42
|
-
"@lowdefy/blocks-aggrid": "4.7.
|
|
43
|
-
"@lowdefy/blocks-antd": "4.7.
|
|
44
|
-
"@lowdefy/blocks-basic": "4.7.
|
|
45
|
-
"@lowdefy/blocks-color-selectors": "4.7.
|
|
46
|
-
"@lowdefy/blocks-echarts": "4.7.
|
|
47
|
-
"@lowdefy/blocks-loaders": "4.7.
|
|
48
|
-
"@lowdefy/blocks-markdown": "4.7.
|
|
49
|
-
"@lowdefy/blocks-qr": "4.7.
|
|
50
|
-
"@lowdefy/build": "4.7.
|
|
51
|
-
"@lowdefy/client": "4.7.
|
|
52
|
-
"@lowdefy/engine": "4.7.
|
|
53
|
-
"@lowdefy/errors": "4.7.
|
|
54
|
-
"@lowdefy/helpers": "4.7.
|
|
55
|
-
"@lowdefy/layout": "4.7.
|
|
56
|
-
"@lowdefy/logger": "4.7.
|
|
57
|
-
"@lowdefy/node-utils": "4.7.
|
|
58
|
-
"@lowdefy/operators-change-case": "4.7.
|
|
59
|
-
"@lowdefy/operators-diff": "4.7.
|
|
60
|
-
"@lowdefy/operators-js": "4.7.
|
|
61
|
-
"@lowdefy/operators-moment": "4.7.
|
|
62
|
-
"@lowdefy/operators-mql": "4.7.
|
|
63
|
-
"@lowdefy/operators-nunjucks": "4.7.
|
|
64
|
-
"@lowdefy/operators-uuid": "4.7.
|
|
65
|
-
"@lowdefy/operators-yaml": "4.7.
|
|
66
|
-
"@lowdefy/plugin-next-auth": "4.7.
|
|
39
|
+
"@lowdefy/actions-core": "4.7.1",
|
|
40
|
+
"@lowdefy/api": "4.7.1",
|
|
41
|
+
"@lowdefy/block-utils": "4.7.1",
|
|
42
|
+
"@lowdefy/blocks-aggrid": "4.7.1",
|
|
43
|
+
"@lowdefy/blocks-antd": "4.7.1",
|
|
44
|
+
"@lowdefy/blocks-basic": "4.7.1",
|
|
45
|
+
"@lowdefy/blocks-color-selectors": "4.7.1",
|
|
46
|
+
"@lowdefy/blocks-echarts": "4.7.1",
|
|
47
|
+
"@lowdefy/blocks-loaders": "4.7.1",
|
|
48
|
+
"@lowdefy/blocks-markdown": "4.7.1",
|
|
49
|
+
"@lowdefy/blocks-qr": "4.7.1",
|
|
50
|
+
"@lowdefy/build": "4.7.1",
|
|
51
|
+
"@lowdefy/client": "4.7.1",
|
|
52
|
+
"@lowdefy/engine": "4.7.1",
|
|
53
|
+
"@lowdefy/errors": "4.7.1",
|
|
54
|
+
"@lowdefy/helpers": "4.7.1",
|
|
55
|
+
"@lowdefy/layout": "4.7.1",
|
|
56
|
+
"@lowdefy/logger": "4.7.1",
|
|
57
|
+
"@lowdefy/node-utils": "4.7.1",
|
|
58
|
+
"@lowdefy/operators-change-case": "4.7.1",
|
|
59
|
+
"@lowdefy/operators-diff": "4.7.1",
|
|
60
|
+
"@lowdefy/operators-js": "4.7.1",
|
|
61
|
+
"@lowdefy/operators-moment": "4.7.1",
|
|
62
|
+
"@lowdefy/operators-mql": "4.7.1",
|
|
63
|
+
"@lowdefy/operators-nunjucks": "4.7.1",
|
|
64
|
+
"@lowdefy/operators-uuid": "4.7.1",
|
|
65
|
+
"@lowdefy/operators-yaml": "4.7.1",
|
|
66
|
+
"@lowdefy/plugin-next-auth": "4.7.1",
|
|
67
67
|
"chokidar": "3.5.3",
|
|
68
68
|
"dotenv": "16.3.1",
|
|
69
69
|
"next": "13.5.4",
|
package/package.original.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lowdefy/server-dev",
|
|
3
|
-
"version": "4.7.
|
|
3
|
+
"version": "4.7.1",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"description": "",
|
|
6
6
|
"homepage": "https://lowdefy.com",
|
|
@@ -44,34 +44,34 @@
|
|
|
44
44
|
"prepublishOnly": "pnpm build"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@lowdefy/actions-core": "4.7.
|
|
48
|
-
"@lowdefy/api": "4.7.
|
|
49
|
-
"@lowdefy/block-utils": "4.7.
|
|
50
|
-
"@lowdefy/blocks-aggrid": "4.7.
|
|
51
|
-
"@lowdefy/blocks-antd": "4.7.
|
|
52
|
-
"@lowdefy/blocks-basic": "4.7.
|
|
53
|
-
"@lowdefy/blocks-color-selectors": "4.7.
|
|
54
|
-
"@lowdefy/blocks-echarts": "4.7.
|
|
55
|
-
"@lowdefy/blocks-loaders": "4.7.
|
|
56
|
-
"@lowdefy/blocks-markdown": "4.7.
|
|
57
|
-
"@lowdefy/blocks-qr": "4.7.
|
|
58
|
-
"@lowdefy/build": "4.7.
|
|
59
|
-
"@lowdefy/client": "4.7.
|
|
60
|
-
"@lowdefy/engine": "4.7.
|
|
61
|
-
"@lowdefy/errors": "4.7.
|
|
62
|
-
"@lowdefy/helpers": "4.7.
|
|
63
|
-
"@lowdefy/layout": "4.7.
|
|
64
|
-
"@lowdefy/logger": "4.7.
|
|
65
|
-
"@lowdefy/node-utils": "4.7.
|
|
66
|
-
"@lowdefy/operators-change-case": "4.7.
|
|
67
|
-
"@lowdefy/operators-diff": "4.7.
|
|
68
|
-
"@lowdefy/operators-js": "4.7.
|
|
69
|
-
"@lowdefy/operators-moment": "4.7.
|
|
70
|
-
"@lowdefy/operators-mql": "4.7.
|
|
71
|
-
"@lowdefy/operators-nunjucks": "4.7.
|
|
72
|
-
"@lowdefy/operators-uuid": "4.7.
|
|
73
|
-
"@lowdefy/operators-yaml": "4.7.
|
|
74
|
-
"@lowdefy/plugin-next-auth": "4.7.
|
|
47
|
+
"@lowdefy/actions-core": "4.7.1",
|
|
48
|
+
"@lowdefy/api": "4.7.1",
|
|
49
|
+
"@lowdefy/block-utils": "4.7.1",
|
|
50
|
+
"@lowdefy/blocks-aggrid": "4.7.1",
|
|
51
|
+
"@lowdefy/blocks-antd": "4.7.1",
|
|
52
|
+
"@lowdefy/blocks-basic": "4.7.1",
|
|
53
|
+
"@lowdefy/blocks-color-selectors": "4.7.1",
|
|
54
|
+
"@lowdefy/blocks-echarts": "4.7.1",
|
|
55
|
+
"@lowdefy/blocks-loaders": "4.7.1",
|
|
56
|
+
"@lowdefy/blocks-markdown": "4.7.1",
|
|
57
|
+
"@lowdefy/blocks-qr": "4.7.1",
|
|
58
|
+
"@lowdefy/build": "4.7.1",
|
|
59
|
+
"@lowdefy/client": "4.7.1",
|
|
60
|
+
"@lowdefy/engine": "4.7.1",
|
|
61
|
+
"@lowdefy/errors": "4.7.1",
|
|
62
|
+
"@lowdefy/helpers": "4.7.1",
|
|
63
|
+
"@lowdefy/layout": "4.7.1",
|
|
64
|
+
"@lowdefy/logger": "4.7.1",
|
|
65
|
+
"@lowdefy/node-utils": "4.7.1",
|
|
66
|
+
"@lowdefy/operators-change-case": "4.7.1",
|
|
67
|
+
"@lowdefy/operators-diff": "4.7.1",
|
|
68
|
+
"@lowdefy/operators-js": "4.7.1",
|
|
69
|
+
"@lowdefy/operators-moment": "4.7.1",
|
|
70
|
+
"@lowdefy/operators-mql": "4.7.1",
|
|
71
|
+
"@lowdefy/operators-nunjucks": "4.7.1",
|
|
72
|
+
"@lowdefy/operators-uuid": "4.7.1",
|
|
73
|
+
"@lowdefy/operators-yaml": "4.7.1",
|
|
74
|
+
"@lowdefy/plugin-next-auth": "4.7.1",
|
|
75
75
|
"chokidar": "3.5.3",
|
|
76
76
|
"dotenv": "16.3.1",
|
|
77
77
|
"next": "13.5.4",
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2026 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import fs from 'fs';
|
|
18
|
+
import path from 'path';
|
|
19
|
+
|
|
20
|
+
async function handler(req, res) {
|
|
21
|
+
const filePath = path.join(process.cwd(), 'build', 'plugins', 'iconsDynamic.js');
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
25
|
+
res.setHeader('Content-Type', 'application/javascript');
|
|
26
|
+
res.status(200).send(content);
|
|
27
|
+
} catch {
|
|
28
|
+
// Return empty default export if file doesn't exist yet
|
|
29
|
+
res.setHeader('Content-Type', 'application/javascript');
|
|
30
|
+
res.status(200).send('export default {};');
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export default handler;
|