@foxford/den 3.0.0 → 3.1.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/README.mdx +266 -2
- package/adapter.cjs +1 -1
- package/adapter.d.cts +1 -1
- package/adapter.d.ts +1 -1
- package/adapter.js +1 -1
- package/bin/den.cjs +88 -0
- package/bin/den.d.cts +2 -0
- package/bin/den.d.ts +2 -0
- package/bin/den.js +88 -0
- package/builder/index.cjs +12 -0
- package/builder/index.d.cts +120 -0
- package/builder/index.d.ts +120 -0
- package/builder/index.js +12 -0
- package/chunk-3RX2OSUL.js +21 -0
- package/{chunk-HJO26HIQ.js → chunk-6FNC3XMI.js} +4 -0
- package/chunk-6QV4L6R2.cjs +21 -0
- package/{chunk-WRQC6BVJ.js → chunk-MCN4GFEQ.js} +4 -19
- package/chunk-OKRO4G4L.cjs +354 -0
- package/chunk-REFU7UMG.js +354 -0
- package/{chunk-XHYR3SGG.cjs → chunk-T5QVCXVB.cjs} +5 -1
- package/chunk-TPHJUDHG.js +230 -0
- package/{chunk-5DJZZML5.cjs → chunk-Z5BL4DJA.cjs} +10 -25
- package/chunk-ZOU6W6ZQ.cjs +230 -0
- package/{define-repository-MDEWHqM7.d.cts → define-repository-CwAXed2X.d.cts} +1 -1
- package/{define-repository-Ca62_YCy.d.ts → define-repository-q_T4hqeP.d.ts} +1 -1
- package/{define-slot-Dil8Kr1A.d.ts → define-slot-Cngzae6i.d.ts} +1 -1
- package/{define-slot-BKvArA02.d.cts → define-slot-DYNCLDJY.d.cts} +1 -1
- package/define.cjs +6 -4
- package/define.d.cts +3 -3
- package/define.d.ts +3 -3
- package/define.js +5 -3
- package/den.js +60 -0
- package/descriptor-DQ6Gi7A_.d.ts +98 -0
- package/descriptor-Dujg_1on.d.cts +98 -0
- package/index.cjs +25 -23
- package/index.d.cts +7 -5
- package/index.d.ts +7 -5
- package/index.js +12 -10
- package/island/index.cjs +12 -157
- package/island/index.d.cts +40 -30
- package/island/index.d.ts +40 -30
- package/island/index.js +19 -164
- package/package.json +59 -16
- package/routes-0uXJ0fux.d.ts +64 -0
- package/routes-B0hDrkiF.d.cts +64 -0
- package/serve/index.cjs +137 -0
- package/serve/index.d.cts +60 -0
- package/serve/index.d.ts +60 -0
- package/serve/index.js +137 -0
- package/server-render-CocWXQKC.d.cts +48 -0
- package/server-render-CocWXQKC.d.ts +48 -0
- package/{types-COwVwgzE.d.cts → types-Dx5qGiwk.d.cts} +1 -1
- package/{types-COwVwgzE.d.ts → types-Dx5qGiwk.d.ts} +1 -1
- package/view-adapter-B4gEb-ms.d.ts +77 -0
- package/view-adapter-DJ7yB6Ml.d.cts +77 -0
- package/view-adapter-BvDC5O4y.d.cts +0 -188
- package/view-adapter-DtNgyjIf.d.ts +0 -188
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
import {
|
|
2
|
+
logger
|
|
3
|
+
} from "./chunk-TPBI6TOU.js";
|
|
4
|
+
import {
|
|
5
|
+
__async,
|
|
6
|
+
__spreadProps,
|
|
7
|
+
__spreadValues
|
|
8
|
+
} from "./chunk-6FNC3XMI.js";
|
|
9
|
+
|
|
10
|
+
// src/builder/config.ts
|
|
11
|
+
function defineAppConfig(config) {
|
|
12
|
+
return config;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// src/builder/build.ts
|
|
16
|
+
import fs2 from "fs";
|
|
17
|
+
import path2 from "path";
|
|
18
|
+
|
|
19
|
+
// src/builder/assets.ts
|
|
20
|
+
import fs from "fs";
|
|
21
|
+
import path from "path";
|
|
22
|
+
var MANIFEST_PATH = ".vite/manifest.json";
|
|
23
|
+
function readManifest(outDir) {
|
|
24
|
+
const manifestPath = path.join(outDir, MANIFEST_PATH);
|
|
25
|
+
if (!fs.existsSync(manifestPath)) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
return JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
|
|
29
|
+
}
|
|
30
|
+
function collectAssets(outDir, base) {
|
|
31
|
+
const manifest = readManifest(outDir);
|
|
32
|
+
if (manifest === null) {
|
|
33
|
+
return { css: [], js: [] };
|
|
34
|
+
}
|
|
35
|
+
const css = [];
|
|
36
|
+
const js = [];
|
|
37
|
+
const seen = /* @__PURE__ */ new Set();
|
|
38
|
+
const prefix = base.endsWith("/") ? base : `${base}/`;
|
|
39
|
+
function walk(key) {
|
|
40
|
+
var _a, _b;
|
|
41
|
+
if (seen.has(key)) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
seen.add(key);
|
|
45
|
+
const chunk = manifest == null ? void 0 : manifest[key];
|
|
46
|
+
if (!chunk) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
for (const imported of (_a = chunk.imports) != null ? _a : []) {
|
|
50
|
+
walk(imported);
|
|
51
|
+
}
|
|
52
|
+
for (const href of (_b = chunk.css) != null ? _b : []) {
|
|
53
|
+
css.push(`${prefix}${href}`);
|
|
54
|
+
}
|
|
55
|
+
js.push(`${prefix}${chunk.file}`);
|
|
56
|
+
}
|
|
57
|
+
for (const [key, chunk] of Object.entries(manifest)) {
|
|
58
|
+
if (chunk.isEntry === true) {
|
|
59
|
+
walk(key);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return { css, js };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// src/builder/entries.ts
|
|
66
|
+
var VIRTUAL_CLIENT = "virtual:den/client";
|
|
67
|
+
var VIRTUAL_SERVER_APP = "virtual:den/server-app";
|
|
68
|
+
var VIRTUAL_SERVER_PROCESS = "virtual:den/server-process";
|
|
69
|
+
var DEFAULT_PORT = 3e3;
|
|
70
|
+
function toResolvedId(id) {
|
|
71
|
+
return `\0${id}`;
|
|
72
|
+
}
|
|
73
|
+
function generateClientEntry(entry, clientEntry) {
|
|
74
|
+
return `import app from ${JSON.stringify(entry)}
|
|
75
|
+
import { hydrateApp } from ${JSON.stringify(clientEntry)}
|
|
76
|
+
|
|
77
|
+
hydrateApp(app)
|
|
78
|
+
`;
|
|
79
|
+
}
|
|
80
|
+
function generateServerApp(entry, configPath, assets) {
|
|
81
|
+
return `import { getAppContainer, viewAdapterOf } from '@foxford/den/island'
|
|
82
|
+
|
|
83
|
+
import app from ${JSON.stringify(entry)}
|
|
84
|
+
import config from ${JSON.stringify(configPath)}
|
|
85
|
+
|
|
86
|
+
const server = config.server ?? {}
|
|
87
|
+
|
|
88
|
+
async function setup() {
|
|
89
|
+
viewAdapterOf(app.viewLayer).installResolver()
|
|
90
|
+
server.container?.(getAppContainer())
|
|
91
|
+
await server.setup?.()
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const descriptor = { ...app, assets: ${JSON.stringify(assets)}, setup }
|
|
95
|
+
|
|
96
|
+
if (server.render) {
|
|
97
|
+
descriptor.serverRender = server.render
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export default descriptor
|
|
101
|
+
`;
|
|
102
|
+
}
|
|
103
|
+
function generateServerProcess(configPath) {
|
|
104
|
+
return `import { serveApp } from '@foxford/den/serve'
|
|
105
|
+
|
|
106
|
+
import app from ${JSON.stringify(VIRTUAL_SERVER_APP)}
|
|
107
|
+
import config from ${JSON.stringify(configPath)}
|
|
108
|
+
|
|
109
|
+
await serveApp(app, {
|
|
110
|
+
configure: config.server?.configure,
|
|
111
|
+
host: process.env.HOST,
|
|
112
|
+
port: Number(process.env.PORT ?? ${String(DEFAULT_PORT)}),
|
|
113
|
+
})
|
|
114
|
+
`;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// src/builder/plugin.ts
|
|
118
|
+
function denAppModules(options) {
|
|
119
|
+
const { assets, config, configPath, entry } = options;
|
|
120
|
+
const sources = {
|
|
121
|
+
[VIRTUAL_CLIENT]: () => generateClientEntry(entry, config.preset.clientEntry),
|
|
122
|
+
[VIRTUAL_SERVER_APP]: () => generateServerApp(entry, configPath, assets),
|
|
123
|
+
[VIRTUAL_SERVER_PROCESS]: () => generateServerProcess(configPath)
|
|
124
|
+
};
|
|
125
|
+
return {
|
|
126
|
+
load: (id) => {
|
|
127
|
+
for (const [virtual, source] of Object.entries(sources)) {
|
|
128
|
+
if (id === toResolvedId(virtual)) {
|
|
129
|
+
return source();
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return null;
|
|
133
|
+
},
|
|
134
|
+
name: "den:app-modules",
|
|
135
|
+
resolveId: (id) => id in sources ? toResolvedId(id) : null
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// src/builder/build.ts
|
|
140
|
+
var CONFIG_FILE = "den.config.ts";
|
|
141
|
+
var OUT_ROOT = "build";
|
|
142
|
+
var OUT_CLIENT = "build/client";
|
|
143
|
+
var OUT_SERVER = "build/server";
|
|
144
|
+
var ENGINE = /^@foxford\/den(\/|$)/;
|
|
145
|
+
function loadAppConfig(root) {
|
|
146
|
+
return __async(this, null, function* () {
|
|
147
|
+
const configPath = path2.join(root, CONFIG_FILE);
|
|
148
|
+
if (!fs2.existsSync(configPath)) {
|
|
149
|
+
throw new Error(`den: ${CONFIG_FILE} \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D \u0432 \xAB${root}\xBB`);
|
|
150
|
+
}
|
|
151
|
+
const { createServer } = yield import("vite");
|
|
152
|
+
const server = yield createServer({
|
|
153
|
+
appType: "custom",
|
|
154
|
+
configFile: false,
|
|
155
|
+
logLevel: "silent",
|
|
156
|
+
root,
|
|
157
|
+
server: { middlewareMode: true }
|
|
158
|
+
});
|
|
159
|
+
try {
|
|
160
|
+
const loaded = yield server.ssrLoadModule(configPath);
|
|
161
|
+
const config = loaded.default;
|
|
162
|
+
if (!(config == null ? void 0 : config.preset)) {
|
|
163
|
+
throw new Error(`den: ${CONFIG_FILE} \u043D\u0435 \u043E\u0431\u044A\u044F\u0432\u043B\u044F\u0435\u0442 \u043F\u0440\u0435\u0441\u0435\u0442 \u0444\u0440\u0435\u0439\u043C\u0432\u043E\u0440\u043A\u0430 \u2014 \u0441\u043E\u0431\u0438\u0440\u0430\u0442\u044C \u043D\u0435\u0447\u0435\u043C`);
|
|
164
|
+
}
|
|
165
|
+
return { config, configPath };
|
|
166
|
+
} finally {
|
|
167
|
+
yield server.close();
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
function dependenciesOf(root) {
|
|
172
|
+
var _a, _b;
|
|
173
|
+
const manifestPath = path2.join(root, "package.json");
|
|
174
|
+
if (!fs2.existsSync(manifestPath)) {
|
|
175
|
+
return [];
|
|
176
|
+
}
|
|
177
|
+
const manifest = JSON.parse(fs2.readFileSync(manifestPath, "utf-8"));
|
|
178
|
+
return [...Object.keys((_a = manifest.dependencies) != null ? _a : {}), ...Object.keys((_b = manifest.devDependencies) != null ? _b : {})];
|
|
179
|
+
}
|
|
180
|
+
function viteConfigFor(options) {
|
|
181
|
+
var _a, _b, _c;
|
|
182
|
+
const { assets, base, config, configPath, entryFileNames, input, outDir, root, target } = options;
|
|
183
|
+
const entry = (_a = config.entry) != null ? _a : "src/index.ts";
|
|
184
|
+
const composed = {
|
|
185
|
+
base,
|
|
186
|
+
build: {
|
|
187
|
+
// Клиентский выход чистит свой каталог сам, серверные — нет: они пишут рядом с уже
|
|
188
|
+
// собранным клиентским, и очистка снесла бы его вместе с манифестом
|
|
189
|
+
emptyOutDir: target === "client",
|
|
190
|
+
manifest: target === "client",
|
|
191
|
+
outDir: path2.join(root, outDir),
|
|
192
|
+
// Вход задаётся `input`, а не `build.ssr`: строку в `build.ssr` сборщик понимает как путь
|
|
193
|
+
// к файлу, а входы у нас виртуальные — их резолвит плагин
|
|
194
|
+
rollupOptions: __spreadValues(__spreadValues({
|
|
195
|
+
input
|
|
196
|
+
}, target === "server" ? { external: [ENGINE] } : {}), entryFileNames === void 0 ? {} : { output: { entryFileNames } }),
|
|
197
|
+
ssr: target === "server"
|
|
198
|
+
},
|
|
199
|
+
configFile: false,
|
|
200
|
+
plugins: [...config.preset.plugins, denAppModules({ assets, config, configPath, entry: path2.join(root, entry) })],
|
|
201
|
+
root,
|
|
202
|
+
ssr: { noExternal: (_c = (_b = config.server) == null ? void 0 : _b.noExternal) != null ? _c : [] }
|
|
203
|
+
};
|
|
204
|
+
return config.vite ? config.vite(composed, target) : composed;
|
|
205
|
+
}
|
|
206
|
+
function buildApp(options) {
|
|
207
|
+
return __async(this, null, function* () {
|
|
208
|
+
var _a, _b;
|
|
209
|
+
const { base = "/" } = options;
|
|
210
|
+
const root = path2.resolve(options.root);
|
|
211
|
+
const { config, configPath } = yield loadAppConfig(root);
|
|
212
|
+
const refusal = (_b = (_a = config.preset).validate) == null ? void 0 : _b.call(_a, dependenciesOf(root));
|
|
213
|
+
if (refusal !== void 0 && refusal !== null) {
|
|
214
|
+
throw new Error(`den: ${refusal}`);
|
|
215
|
+
}
|
|
216
|
+
const { build } = yield import("vite");
|
|
217
|
+
const shared = { base, config, configPath, root };
|
|
218
|
+
const empty = { css: [], js: [] };
|
|
219
|
+
logger.info(`\u0441\u0431\u043E\u0440\u043A\u0430 \u043A\u043B\u0438\u0435\u043D\u0442\u0441\u043A\u043E\u0433\u043E \u0432\u044B\u0445\u043E\u0434\u0430 (${config.preset.view})`);
|
|
220
|
+
yield build(viteConfigFor(__spreadProps(__spreadValues({}, shared), { assets: empty, input: VIRTUAL_CLIENT, outDir: OUT_CLIENT, target: "client" })));
|
|
221
|
+
const assets = collectAssets(path2.join(root, OUT_CLIENT), base);
|
|
222
|
+
logger.info(`\u0430\u0440\u0442\u0435\u0444\u0430\u043A\u0442\u044B: ${String(assets.js.length)} js, ${String(assets.css.length)} css`);
|
|
223
|
+
logger.info("\u0441\u0431\u043E\u0440\u043A\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u043D\u043E\u0433\u043E \u0434\u0435\u0441\u043A\u0440\u0438\u043F\u0442\u043E\u0440\u0430");
|
|
224
|
+
yield build(
|
|
225
|
+
viteConfigFor(__spreadProps(__spreadValues({}, shared), {
|
|
226
|
+
assets,
|
|
227
|
+
entryFileNames: "index.mjs",
|
|
228
|
+
input: VIRTUAL_SERVER_APP,
|
|
229
|
+
outDir: OUT_SERVER,
|
|
230
|
+
target: "server"
|
|
231
|
+
}))
|
|
232
|
+
);
|
|
233
|
+
logger.info("\u0441\u0431\u043E\u0440\u043A\u0430 \u0442\u043E\u0447\u043A\u0438 \u0432\u0445\u043E\u0434\u0430 \u043F\u0440\u043E\u0446\u0435\u0441\u0441\u0430");
|
|
234
|
+
yield build(
|
|
235
|
+
viteConfigFor(__spreadProps(__spreadValues({}, shared), {
|
|
236
|
+
assets,
|
|
237
|
+
entryFileNames: "server.mjs",
|
|
238
|
+
input: VIRTUAL_SERVER_PROCESS,
|
|
239
|
+
outDir: OUT_ROOT,
|
|
240
|
+
target: "server"
|
|
241
|
+
}))
|
|
242
|
+
);
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// src/builder/dev.ts
|
|
247
|
+
import { spawn } from "child_process";
|
|
248
|
+
import fs3 from "fs";
|
|
249
|
+
import path3 from "path";
|
|
250
|
+
var SERVER_ENTRY = "build/server.mjs";
|
|
251
|
+
var WATCHED = ["src", "den.config.ts"];
|
|
252
|
+
var DEBOUNCE_MS = 150;
|
|
253
|
+
var SHUTDOWN_TIMEOUT_MS = 5e3;
|
|
254
|
+
function devApp(options) {
|
|
255
|
+
return __async(this, null, function* () {
|
|
256
|
+
const root = path3.resolve(options.root);
|
|
257
|
+
const entry = path3.join(root, SERVER_ENTRY);
|
|
258
|
+
let child = null;
|
|
259
|
+
let pending = null;
|
|
260
|
+
let building = false;
|
|
261
|
+
let dirty = false;
|
|
262
|
+
function signalGroup(pid, signal) {
|
|
263
|
+
try {
|
|
264
|
+
process.kill(-pid, signal);
|
|
265
|
+
} catch (e) {
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
function stop() {
|
|
269
|
+
return __async(this, null, function* () {
|
|
270
|
+
const running = child;
|
|
271
|
+
child = null;
|
|
272
|
+
if (!running || running.exitCode !== null || running.pid === void 0) {
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
const { pid } = running;
|
|
276
|
+
yield new Promise((resolve) => {
|
|
277
|
+
const forced = setTimeout(() => signalGroup(pid, "SIGKILL"), SHUTDOWN_TIMEOUT_MS);
|
|
278
|
+
running.once("exit", () => {
|
|
279
|
+
clearTimeout(forced);
|
|
280
|
+
resolve();
|
|
281
|
+
});
|
|
282
|
+
signalGroup(pid, "SIGTERM");
|
|
283
|
+
});
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
function start() {
|
|
287
|
+
const started = spawn(process.execPath, [...process.execArgv, entry], {
|
|
288
|
+
detached: true,
|
|
289
|
+
stdio: "inherit"
|
|
290
|
+
});
|
|
291
|
+
child = started;
|
|
292
|
+
started.on("exit", (code, signal) => {
|
|
293
|
+
if (child !== started) {
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
child = null;
|
|
297
|
+
logger.error(`\u043F\u0440\u043E\u0446\u0435\u0441\u0441 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043B\u0441\u044F \u0441\u0430\u043C (\u043A\u043E\u0434 ${String(code)}, \u0441\u0438\u0433\u043D\u0430\u043B ${String(signal)})`);
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
function rebuild() {
|
|
301
|
+
return __async(this, null, function* () {
|
|
302
|
+
if (building) {
|
|
303
|
+
dirty = true;
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
building = true;
|
|
307
|
+
try {
|
|
308
|
+
do {
|
|
309
|
+
dirty = false;
|
|
310
|
+
yield stop();
|
|
311
|
+
try {
|
|
312
|
+
yield buildApp(options);
|
|
313
|
+
start();
|
|
314
|
+
} catch (error) {
|
|
315
|
+
logger.error("\u0441\u0431\u043E\u0440\u043A\u0430 \u043D\u0435 \u043F\u0440\u043E\u0448\u043B\u0430, \u0436\u0434\u0443 \u043F\u0440\u0430\u0432\u043A\u0438:", error);
|
|
316
|
+
}
|
|
317
|
+
} while (dirty);
|
|
318
|
+
} finally {
|
|
319
|
+
building = false;
|
|
320
|
+
}
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
yield rebuild();
|
|
324
|
+
for (const target of WATCHED) {
|
|
325
|
+
const watched = path3.join(root, target);
|
|
326
|
+
if (!fs3.existsSync(watched)) {
|
|
327
|
+
continue;
|
|
328
|
+
}
|
|
329
|
+
fs3.watch(watched, { recursive: true }, () => {
|
|
330
|
+
if (pending) {
|
|
331
|
+
clearTimeout(pending);
|
|
332
|
+
}
|
|
333
|
+
pending = setTimeout(() => void rebuild(), DEBOUNCE_MS);
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
logger.info(`\u0436\u0434\u0443 \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u0439 \u0432 ${WATCHED.join(", ")}`);
|
|
337
|
+
for (const signal of ["SIGINT", "SIGTERM"]) {
|
|
338
|
+
process.once(signal, () => {
|
|
339
|
+
void stop().then(() => process.exit(0));
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
process.on("exit", () => {
|
|
343
|
+
if ((child == null ? void 0 : child.pid) !== void 0) {
|
|
344
|
+
signalGroup(child.pid, "SIGTERM");
|
|
345
|
+
}
|
|
346
|
+
});
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
export {
|
|
351
|
+
defineAppConfig,
|
|
352
|
+
buildApp,
|
|
353
|
+
devApp
|
|
354
|
+
};
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true});var __defProp = Object.defineProperty;
|
|
2
|
+
var __defProps = Object.defineProperties;
|
|
3
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
2
4
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
3
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
4
6
|
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
@@ -14,6 +16,7 @@ var __spreadValues = (a, b) => {
|
|
|
14
16
|
}
|
|
15
17
|
return a;
|
|
16
18
|
};
|
|
19
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
17
20
|
var __async = (__this, __arguments, generator) => {
|
|
18
21
|
return new Promise((resolve, reject) => {
|
|
19
22
|
var fulfilled = (value) => {
|
|
@@ -38,4 +41,5 @@ var __async = (__this, __arguments, generator) => {
|
|
|
38
41
|
|
|
39
42
|
|
|
40
43
|
|
|
41
|
-
|
|
44
|
+
|
|
45
|
+
exports.__spreadValues = __spreadValues; exports.__spreadProps = __spreadProps; exports.__async = __async;
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import {
|
|
2
|
+
resolveViewAdapter
|
|
3
|
+
} from "./chunk-E23E2VUC.js";
|
|
4
|
+
import {
|
|
5
|
+
RequestContextToken
|
|
6
|
+
} from "./chunk-3RX2OSUL.js";
|
|
7
|
+
import {
|
|
8
|
+
LoggerToken,
|
|
9
|
+
logger,
|
|
10
|
+
unitLogger
|
|
11
|
+
} from "./chunk-TPBI6TOU.js";
|
|
12
|
+
import {
|
|
13
|
+
__async,
|
|
14
|
+
__spreadValues
|
|
15
|
+
} from "./chunk-6FNC3XMI.js";
|
|
16
|
+
|
|
17
|
+
// src/island/document.ts
|
|
18
|
+
function isDocumentSource(value) {
|
|
19
|
+
return typeof value === "object" && value !== null && typeof value.describeDocument === "function";
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// src/island/runtime.ts
|
|
23
|
+
import { Container } from "@foxford/ioc";
|
|
24
|
+
var appContainer = null;
|
|
25
|
+
function getAppContainer() {
|
|
26
|
+
var _a;
|
|
27
|
+
if (appContainer === null) {
|
|
28
|
+
appContainer = new Container();
|
|
29
|
+
((_a = logger.getLogger("island:runtime")) != null ? _a : logger).debug("app-\u043A\u043E\u043D\u0442\u0435\u0439\u043D\u0435\u0440 \u0441\u043E\u0437\u0434\u0430\u043D");
|
|
30
|
+
}
|
|
31
|
+
return appContainer;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// src/island/lifecycle.ts
|
|
35
|
+
import { log } from "@foxford/logger";
|
|
36
|
+
var EMPTY_ROUTE = { params: {}, pathname: "", search: "" };
|
|
37
|
+
var REDIRECT_FOUND = 302;
|
|
38
|
+
function createIslandContainer(descriptor, options = {}) {
|
|
39
|
+
var _a, _b, _c, _d, _e;
|
|
40
|
+
const { parent = getAppContainer() } = options;
|
|
41
|
+
const appLog = (_b = log.getLogger((_a = descriptor.name) != null ? _a : "app")) != null ? _b : logger;
|
|
42
|
+
const islandLog = (_c = appLog.getLogger("client")) != null ? _c : appLog;
|
|
43
|
+
try {
|
|
44
|
+
const container = parent.createChild();
|
|
45
|
+
container.bind(LoggerToken).toValue(islandLog);
|
|
46
|
+
descriptor.viewLayer.register(container);
|
|
47
|
+
const viewModels = (_d = descriptor.viewModels) != null ? _d : [];
|
|
48
|
+
const slots = Object.entries((_e = descriptor.slots) != null ? _e : {});
|
|
49
|
+
islandLog.info(
|
|
50
|
+
`\u043E\u0441\u0442\u0440\u043E\u0432: \u043A\u043E\u043D\u0442\u0435\u0439\u043D\u0435\u0440 \u0441\u043E\u0437\u0434\u0430\u043D (units=${descriptor.units.length}, vms=${viewModels.length}, slots=${slots.length})`
|
|
51
|
+
);
|
|
52
|
+
for (const unit of descriptor.units) {
|
|
53
|
+
unit.register(container);
|
|
54
|
+
}
|
|
55
|
+
for (const vm of viewModels) {
|
|
56
|
+
vm.register(container);
|
|
57
|
+
}
|
|
58
|
+
for (const [name, slot] of slots) {
|
|
59
|
+
slot.register(container, name);
|
|
60
|
+
}
|
|
61
|
+
return container;
|
|
62
|
+
} catch (error) {
|
|
63
|
+
islandLog.error("\u043E\u0441\u0442\u0440\u043E\u0432: \u0441\u0431\u043E\u0440\u043A\u0430 \u043A\u043E\u043D\u0442\u0435\u0439\u043D\u0435\u0440\u0430 \u0443\u043F\u0430\u043B\u0430", error);
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function hydrateIslandState(container, descriptor, denState) {
|
|
68
|
+
var _a, _b;
|
|
69
|
+
for (const vm of (_a = descriptor.viewModels) != null ? _a : []) {
|
|
70
|
+
const instance = container.resolve(vm.token);
|
|
71
|
+
const saved = denState[vm.token.description];
|
|
72
|
+
if (saved !== void 0 && typeof ((_b = instance.state) == null ? void 0 : _b.set) === "function") {
|
|
73
|
+
unitLogger(container, vm.token.description).debug("\u0433\u0438\u0434\u0440\u0430\u0446\u0438\u044F VM \u0438\u0437 denState");
|
|
74
|
+
instance.state.set(saved);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
function activateIslandViewModels(_0, _1) {
|
|
79
|
+
return __async(this, arguments, function* (container, descriptor, route = EMPTY_ROUTE) {
|
|
80
|
+
var _a;
|
|
81
|
+
yield Promise.all(
|
|
82
|
+
((_a = descriptor.viewModels) != null ? _a : []).map((vm) => __async(null, null, function* () {
|
|
83
|
+
var _a2;
|
|
84
|
+
const instance = container.resolve(vm.token);
|
|
85
|
+
unitLogger(container, vm.token.description).debug(`\u0430\u043A\u0442\u0438\u0432\u0430\u0446\u0438\u044F VM (${route.pathname || "\u2014"})`);
|
|
86
|
+
yield (_a2 = instance.activate) == null ? void 0 : _a2.call(instance, route);
|
|
87
|
+
}))
|
|
88
|
+
);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
function collectIslandState(container, descriptor) {
|
|
92
|
+
var _a, _b;
|
|
93
|
+
const state = {};
|
|
94
|
+
for (const vm of (_a = descriptor.viewModels) != null ? _a : []) {
|
|
95
|
+
const instance = container.resolve(vm.token);
|
|
96
|
+
if (typeof ((_b = instance.state) == null ? void 0 : _b.get) === "function") {
|
|
97
|
+
state[vm.token.description] = instance.state.get();
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return state;
|
|
101
|
+
}
|
|
102
|
+
function collectDocumentContribution(container, descriptor) {
|
|
103
|
+
var _a, _b;
|
|
104
|
+
const contribution = {};
|
|
105
|
+
for (const vm of (_a = descriptor.viewModels) != null ? _a : []) {
|
|
106
|
+
const instance = container.resolve(vm.token);
|
|
107
|
+
if (!isDocumentSource(instance)) {
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
const part = instance.describeDocument();
|
|
111
|
+
if (part.head) {
|
|
112
|
+
contribution.head = __spreadValues(__spreadValues({}, contribution.head), part.head);
|
|
113
|
+
}
|
|
114
|
+
const declared = part.status !== void 0 || part.redirect !== void 0;
|
|
115
|
+
if (declared && contribution.status === void 0) {
|
|
116
|
+
contribution.status = (_b = part.status) != null ? _b : REDIRECT_FOUND;
|
|
117
|
+
contribution.redirect = part.redirect;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return contribution;
|
|
121
|
+
}
|
|
122
|
+
function resolveEagerUnits(container, descriptor) {
|
|
123
|
+
var _a;
|
|
124
|
+
for (const token of (_a = descriptor.eager) != null ? _a : []) {
|
|
125
|
+
const instance = container.resolve(token);
|
|
126
|
+
unitLogger(container, token.description).debug("eager: \u0435\u0434\u0438\u043D\u0438\u0446\u0430 \u043F\u043E\u0434\u043D\u044F\u0442\u0430 \u043F\u0440\u0438 \u043C\u043E\u043D\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u0438");
|
|
127
|
+
if (instance instanceof Promise) {
|
|
128
|
+
instance.catch(
|
|
129
|
+
(error) => unitLogger(container, token.description).error("eager: \u0435\u0434\u0438\u043D\u0438\u0446\u0430 \u043D\u0435 \u043F\u043E\u0434\u043D\u044F\u043B\u0430\u0441\u044C", error)
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// src/island/render.ts
|
|
136
|
+
var STATUS_OK = 200;
|
|
137
|
+
var processSetup = /* @__PURE__ */ new WeakMap();
|
|
138
|
+
function setupOnce(descriptor) {
|
|
139
|
+
const { setup } = descriptor;
|
|
140
|
+
if (!setup) {
|
|
141
|
+
return Promise.resolve();
|
|
142
|
+
}
|
|
143
|
+
let started = processSetup.get(descriptor);
|
|
144
|
+
if (!started) {
|
|
145
|
+
started = Promise.resolve(setup());
|
|
146
|
+
processSetup.set(descriptor, started);
|
|
147
|
+
}
|
|
148
|
+
return started;
|
|
149
|
+
}
|
|
150
|
+
function renderApp(descriptor, request) {
|
|
151
|
+
return __async(this, null, function* () {
|
|
152
|
+
var _a, _b;
|
|
153
|
+
yield setupOnce(descriptor);
|
|
154
|
+
const route = {
|
|
155
|
+
params: (_a = request.params) != null ? _a : {},
|
|
156
|
+
pathname: request.pathname,
|
|
157
|
+
search: (_b = request.search) != null ? _b : ""
|
|
158
|
+
};
|
|
159
|
+
const container = createIslandContainer(descriptor, { parent: request.parent });
|
|
160
|
+
if (container === null) {
|
|
161
|
+
throw new Error(`den/island: \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0435 \xAB${descriptor.name}\xBB \u043D\u0435 \u0441\u043E\u0431\u0440\u0430\u043B\u043E\u0441\u044C \u2014 \u0440\u0435\u043D\u0434\u0435\u0440 \u043D\u0435\u0432\u043E\u0437\u043C\u043E\u0436\u0435\u043D`);
|
|
162
|
+
}
|
|
163
|
+
try {
|
|
164
|
+
if (request.context) {
|
|
165
|
+
container.bind(RequestContextToken).toValue(request.context);
|
|
166
|
+
}
|
|
167
|
+
yield activateIslandViewModels(container, descriptor, route);
|
|
168
|
+
const { head, redirect, status = STATUS_OK } = collectDocumentContribution(container, descriptor);
|
|
169
|
+
if (status !== STATUS_OK) {
|
|
170
|
+
return { head, html: "", redirect, state: {}, status };
|
|
171
|
+
}
|
|
172
|
+
const state = collectIslandState(container, descriptor);
|
|
173
|
+
const rendered = resolveViewAdapter(container).renderIsland(descriptor, {
|
|
174
|
+
container,
|
|
175
|
+
slots: request.slots
|
|
176
|
+
});
|
|
177
|
+
return { assets: descriptor.assets, head, headHtml: rendered.head, html: rendered.html, state, status };
|
|
178
|
+
} finally {
|
|
179
|
+
yield container.dispose();
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// src/island/routes.ts
|
|
185
|
+
function normalizeRoutes(routes = []) {
|
|
186
|
+
return routes.map((route) => typeof route === "string" ? { source: route } : route);
|
|
187
|
+
}
|
|
188
|
+
function matchRoute(routes = [], pathname) {
|
|
189
|
+
for (const route of normalizeRoutes(routes)) {
|
|
190
|
+
const found = new RegExp(route.source).exec(pathname);
|
|
191
|
+
if (found !== null) {
|
|
192
|
+
return { params: decodeParams(found.groups), route };
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
function decodeParams(groups) {
|
|
198
|
+
const params = {};
|
|
199
|
+
for (const [name, value] of Object.entries(groups != null ? groups : {})) {
|
|
200
|
+
if (value === void 0) {
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
try {
|
|
204
|
+
params[name] = decodeURIComponent(value);
|
|
205
|
+
} catch (e) {
|
|
206
|
+
params[name] = value;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return params;
|
|
210
|
+
}
|
|
211
|
+
var REGEXP_SPECIALS = /[.*+?^${}()|[\]\\]/g;
|
|
212
|
+
var PARAM_SEGMENT = /\/:([A-Za-z_$][\w$]*)/g;
|
|
213
|
+
function pathPattern(pattern) {
|
|
214
|
+
return `^${pattern.replace(REGEXP_SPECIALS, "\\$&").replace(PARAM_SEGMENT, "/(?<$1>[^/]+)")}$`;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
export {
|
|
218
|
+
isDocumentSource,
|
|
219
|
+
getAppContainer,
|
|
220
|
+
createIslandContainer,
|
|
221
|
+
hydrateIslandState,
|
|
222
|
+
activateIslandViewModels,
|
|
223
|
+
collectIslandState,
|
|
224
|
+
collectDocumentContribution,
|
|
225
|
+
resolveEagerUnits,
|
|
226
|
+
renderApp,
|
|
227
|
+
normalizeRoutes,
|
|
228
|
+
matchRoute,
|
|
229
|
+
pathPattern
|
|
230
|
+
};
|
|
@@ -3,18 +3,11 @@
|
|
|
3
3
|
var _chunkC7BM4DGXcjs = require('./chunk-C7BM4DGX.cjs');
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
var _chunkA6ZPAM6Zcjs = require('./chunk-A6ZPAM6Z.cjs');
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
var
|
|
12
|
-
var NavigationManagerToken = _ioc.createToken.call(void 0, "core:NavigationManager");
|
|
13
|
-
var StateSerializerToken = _ioc.createToken.call(void 0, "core:StateSerializer");
|
|
14
|
-
var StateRegistryToken = _ioc.createToken.call(void 0, "core:StateRegistry");
|
|
15
|
-
var SlotRegistryToken = _ioc.createToken.call(void 0, "core:SlotRegistry");
|
|
16
|
-
var ActivatableToken = _ioc.createToken.call(void 0, "core:Activatable");
|
|
17
|
-
var RequestContextToken = _ioc.createToken.call(void 0, "core:RequestContext");
|
|
7
|
+
var _chunk6QV4L6R2cjs = require('./chunk-6QV4L6R2.cjs');
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
var _chunkA6ZPAM6Zcjs = require('./chunk-A6ZPAM6Z.cjs');
|
|
18
11
|
|
|
19
12
|
// src/core/slot-registry.ts
|
|
20
13
|
var SlotRegistry = class {
|
|
@@ -45,7 +38,7 @@ var SlotRegistry = class {
|
|
|
45
38
|
};
|
|
46
39
|
|
|
47
40
|
// src/define-service.ts
|
|
48
|
-
|
|
41
|
+
var _ioc = require('@foxford/ioc');
|
|
49
42
|
function defineService(token, options) {
|
|
50
43
|
const { requires, create, activate, deactivate, serialize, deserialize, scope } = options;
|
|
51
44
|
const requireTokens = requires != null ? requires : [];
|
|
@@ -92,10 +85,10 @@ function defineService(token, options) {
|
|
|
92
85
|
};
|
|
93
86
|
}
|
|
94
87
|
function registerStateParticipant(container, token, instance, deps, serialize, deserialize) {
|
|
95
|
-
if (!container.has(StateRegistryToken)) {
|
|
88
|
+
if (!container.has(_chunk6QV4L6R2cjs.StateRegistryToken)) {
|
|
96
89
|
return;
|
|
97
90
|
}
|
|
98
|
-
const resolved = container.resolve(StateRegistryToken);
|
|
91
|
+
const resolved = container.resolve(_chunk6QV4L6R2cjs.StateRegistryToken);
|
|
99
92
|
if (resolved instanceof Promise) {
|
|
100
93
|
return;
|
|
101
94
|
}
|
|
@@ -192,9 +185,9 @@ function defineSlot({ view, units = [], viewLayer } = {}) {
|
|
|
192
185
|
for (const unit of units) {
|
|
193
186
|
unit.register(container);
|
|
194
187
|
}
|
|
195
|
-
const registry = container.has(SlotRegistryToken) ? container.resolve(SlotRegistryToken) : (() => {
|
|
188
|
+
const registry = container.has(_chunk6QV4L6R2cjs.SlotRegistryToken) ? container.resolve(_chunk6QV4L6R2cjs.SlotRegistryToken) : (() => {
|
|
196
189
|
const created = new SlotRegistry();
|
|
197
|
-
container.bind(SlotRegistryToken).toValue(created);
|
|
190
|
+
container.bind(_chunk6QV4L6R2cjs.SlotRegistryToken).toValue(created);
|
|
198
191
|
slotLog.debug("\u0441\u043E\u0437\u0434\u0430\u043D SlotRegistry \u043A\u043E\u043D\u0442\u0435\u0439\u043D\u0435\u0440\u0430");
|
|
199
192
|
return created;
|
|
200
193
|
})();
|
|
@@ -213,12 +206,4 @@ function defineSlot({ view, units = [], viewLayer } = {}) {
|
|
|
213
206
|
|
|
214
207
|
|
|
215
208
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
exports.ContainerManagerToken = ContainerManagerToken; exports.GuardRunnerToken = GuardRunnerToken; exports.NavigationManagerToken = NavigationManagerToken; exports.StateSerializerToken = StateSerializerToken; exports.StateRegistryToken = StateRegistryToken; exports.SlotRegistryToken = SlotRegistryToken; exports.ActivatableToken = ActivatableToken; exports.RequestContextToken = RequestContextToken; exports.SlotRegistry = SlotRegistry; exports.defineService = defineService; exports.defineViewModel = defineViewModel; exports.defineRepository = defineRepository; exports.defineSlot = defineSlot;
|
|
209
|
+
exports.SlotRegistry = SlotRegistry; exports.defineService = defineService; exports.defineViewModel = defineViewModel; exports.defineRepository = defineRepository; exports.defineSlot = defineSlot;
|