@blocklet/pages-kit-inner-components 0.6.0 → 0.6.2

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.
Files changed (45) hide show
  1. package/lib/cjs/add-component.js +1 -420
  2. package/lib/cjs/chunks/draft-data-CfIMszE7.js +1 -0
  3. package/lib/cjs/chunks/home-DUjl5PbP.js +6 -0
  4. package/lib/cjs/chunks/publish-button-C522nNv6.js +1 -0
  5. package/lib/cjs/chunks/site-state-DDXqWF74.js +57 -0
  6. package/lib/cjs/chunks/state-CtNs8GrN.js +1 -0
  7. package/lib/cjs/home.js +1 -1
  8. package/lib/cjs/project-html.js +11 -4
  9. package/lib/cjs/resources.js +1 -1
  10. package/lib/es/add-component.js +2 -1089
  11. package/lib/es/chunks/{draft-data-CafrGKeh.js → draft-data-bRUHvvzp.js} +5 -4
  12. package/lib/es/chunks/home-VWWdvIPQ.js +69 -0
  13. package/lib/es/chunks/{publish-button-XSZrDaTQ.js → publish-button-Ceet-m88.js} +158 -140
  14. package/lib/es/chunks/site-state-Bh8guIeX.js +2092 -0
  15. package/lib/es/chunks/state-BdNIIXJP.js +502 -0
  16. package/lib/es/home.js +3 -28
  17. package/lib/es/project-html.js +114 -130
  18. package/lib/es/resources.js +93 -137
  19. package/package.json +11 -11
  20. package/lib/cjs/chunks/draft-data-D44_IEV2.js +0 -1
  21. package/lib/cjs/chunks/home-BYk01EUy.js +0 -39
  22. package/lib/cjs/chunks/index-BRgYwvuv.js +0 -475
  23. package/lib/cjs/chunks/publish-button-C8XPA4g_.js +0 -1
  24. package/lib/cjs/chunks/session-BRtsDvA-.js +0 -1
  25. package/lib/cjs/chunks/site-state-gSkcvhcV.js +0 -57
  26. package/lib/cjs/chunks/state-B6BF5wJ-.js +0 -1
  27. package/lib/cjs/chunks-map.json +0 -1
  28. package/lib/cjs/components.js +0 -1
  29. package/lib/cjs/locales.js +0 -3
  30. package/lib/cjs/setting.js +0 -11
  31. package/lib/cjs/site-state.js +0 -1
  32. package/lib/cjs/theme.js +0 -1
  33. package/lib/cjs/uploader.js +0 -1
  34. package/lib/es/chunks/home-DW8SdyfO.js +0 -594
  35. package/lib/es/chunks/index-D5gXPe_7.js +0 -2326
  36. package/lib/es/chunks/session-C72Dq8zg.js +0 -19
  37. package/lib/es/chunks/site-state-W2H7XCSQ.js +0 -2077
  38. package/lib/es/chunks/state-0gvZF3k2.js +0 -573
  39. package/lib/es/chunks-map.json +0 -1
  40. package/lib/es/components.js +0 -22
  41. package/lib/es/locales.js +0 -1032
  42. package/lib/es/setting.js +0 -2294
  43. package/lib/es/site-state.js +0 -48
  44. package/lib/es/theme.js +0 -484
  45. package/lib/es/uploader.js +0 -8
@@ -0,0 +1,2092 @@
1
+ import { getComponentMountPoint as dt } from "@blocklet/pages-kit/builtin/utils";
2
+ import { PreloadComponentScriptModule as Ie } from "@blocklet/pages-kit/types";
3
+ import { componentUMDName as ft, RenderNestedComponent as ke, mergeComponent as mt, getComponentDependencies as ht } from "@blocklet/pages-kit/utils/property";
4
+ import { memoize as gt, BuiltinModules as ge } from "@blocklet/quickjs";
5
+ import { BuiltinModules as Ee } from "@blocklet/pages-kit/utils/builtin";
6
+ import E from "@blocklet/sdk/lib/config";
7
+ import { LRUCache as le } from "lru-cache";
8
+ import yt, { Headers as St } from "node-fetch";
9
+ import { joinURL as V, getQuery as wt, withQuery as It, parseURL as De, withHttps as Et } from "ufo";
10
+ import Pe from "lodash/isEmpty";
11
+ import { createHash as bt } from "crypto";
12
+ import { promises as M, readFileSync as J, mkdtempSync as Pt, existsSync as L, lstatSync as G, rmSync as Je, renameSync as Re, mkdirSync as F, writeFileSync as oe, copyFileSync as At, readdirSync as Ct, createWriteStream as Ot } from "fs";
13
+ import Ke, { join as P, dirname as j, basename as x } from "path";
14
+ import vt from "lodash/isNil";
15
+ import Tt from "@blocklet/logger";
16
+ import { isRelativeModule as kt, createBuiltinModuleTransformer as Dt } from "@blocklet/pages-kit/utils/typescript/builtin-module-transformer";
17
+ import { getResources as Rt, getComponentWebEndpoint as xt, call as jt } from "@blocklet/sdk/lib/component";
18
+ import { getYjsValue as z, syncedStore as $t } from "@syncedstore/core";
19
+ import * as _ from "yjs";
20
+ import { setPageDataSource as Mt } from "@blocklet/pages-kit/utils/data-source";
21
+ import { getRouteMetaDataByOptionIds as Lt, generateParamCombinations as Ae } from "@blocklet/pages-kit/utils/route";
22
+ import { cloneDeep as Nt } from "lodash";
23
+ import { nextId as xe } from "@blocklet/pages-kit/utils/common";
24
+ import { unzipSection as _t } from "@blocklet/pages-kit/utils/page-model";
25
+ import { reactive as Ut } from "@reactivedata/reactive";
26
+ import { globSync as se } from "glob";
27
+ import * as ye from "lib0/decoding";
28
+ import * as D from "lib0/encoding";
29
+ import Ft from "lodash/cloneDeep";
30
+ import ze from "lodash/debounce";
31
+ import Ce from "lodash/get";
32
+ import je from "lodash/set";
33
+ import Bt from "lodash/union";
34
+ import Vt from "p-limit";
35
+ import { DataTypes as k, Sequelize as Gt, Model as He, Op as We } from "sequelize";
36
+ import { pipeline as Jt } from "stream/promises";
37
+ import { x as Kt } from "tar";
38
+ import zt from "wait-on";
39
+ import { Awareness as Ht, encodeAwarenessUpdate as $e, removeAwarenessStates as Wt, applyAwarenessUpdate as Yt } from "y-protocols/awareness";
40
+ import { writeUpdate as qt, writeSyncStep1 as Qt, readSyncMessage as Xt } from "y-protocols/sync";
41
+ import * as K from "yaml";
42
+ import "sqlite3";
43
+ import "@blocklet/pages-kit/types/state";
44
+ E.env.mode;
45
+ E.env.OPENAI_API_KEY || process.env.OPENAI_API_KEY;
46
+ E.env.OPENAI_BASE_URL || process.env.OPENAI_BASE_URL;
47
+ E.env.TRANSLATE_ADDITIONAL_PROMPT || process.env.TRANSLATE_ADDITIONAL_PROMPT;
48
+ E.env.PAGE_CONTENT_ADDITIONAL_PROMPT || process.env.PAGE_CONTENT_ADDITIONAL_PROMPT;
49
+ const Zt = "image-bin";
50
+ E.env.INIT_TEMPLATE_PATH;
51
+ const Ye = process.env.DATABASE_URL || Ke.join(E.env.dataDir, "db/pages-kit.db"), Me = E, Ns = () => E.env.tenantMode === "multiple", _s = () => (vt(Me.env.preferences.multiTenantAllProjectAccessPassports) ? [] : Me.env.preferences.multiTenantAllProjectAccessPassports?.split(",")) || [], eo = Ke.join(E.env.dataDir, "fs-memoize-cache"), to = E.env.FS_MEMOIZE_CACHE_VERSION || "v1.0.0", f = Tt("pages-kit"), oo = k.sqlite.DATE.parse;
52
+ k.sqlite.DATE.parse = (t, e) => typeof t == "number" ? new Date(t) : oo(t, e);
53
+ const U = new Gt({
54
+ dialect: "sqlite",
55
+ storage: Ye,
56
+ benchmark: process.env.ENABLE_SEQUELIZE_BENCHMARK === "true",
57
+ retry: {
58
+ match: [/SQLITE_BUSY/],
59
+ name: "query",
60
+ max: 10
61
+ },
62
+ // eslint-disable-next-line no-console
63
+ logging: process.env.ENABLE_SEQUELIZE_LOGGING === "true" ? console.log : !1
64
+ // logQueryParameters: true,
65
+ });
66
+ U.query("pragma journal_mode = WAL;");
67
+ U.query("pragma synchronous = normal;");
68
+ U.query("pragma journal_size_limit = 33554432;");
69
+ U.query("pragma cache_size = -2000;");
70
+ U.query("pragma mmap_size = 33554432;");
71
+ process.on("SIGINT", async () => {
72
+ await U.close(), process.exit(0);
73
+ });
74
+ process.on("SIGTERM", async () => {
75
+ await U.close(), process.exit(0);
76
+ });
77
+ async function so(t, e) {
78
+ try {
79
+ if (t.getDialect() !== "sqlite")
80
+ return;
81
+ const [o] = await t.query("SELECT 1");
82
+ if (!o || o.length === 0)
83
+ return;
84
+ await t.query("PRAGMA shrink_memory;");
85
+ } catch (o) {
86
+ if (o.name === "SequelizeConnectionError" || o?.message && /closed!/.test(o.message))
87
+ return;
88
+ console.error("Failed to cleanup SQLite memory", e, o);
89
+ }
90
+ }
91
+ setInterval(
92
+ async () => {
93
+ f.info("Start cleanupSqliteMemory"), await so(U, Ye), f.info("End cleanupSqliteMemory");
94
+ },
95
+ 60 * 1e3 * 10
96
+ // 10 minutes
97
+ );
98
+ class Oe extends He {
99
+ // Foreign key to Component
100
+ }
101
+ Oe.init(
102
+ {
103
+ id: {
104
+ type: k.UUID,
105
+ allowNull: !1,
106
+ primaryKey: !0,
107
+ defaultValue: k.UUIDV4
108
+ },
109
+ projectId: {
110
+ type: k.UUID,
111
+ allowNull: !1
112
+ },
113
+ componentId: {
114
+ type: k.STRING,
115
+ allowNull: !1
116
+ }
117
+ },
118
+ { sequelize: U, tableName: "ProjectComponents", timestamps: !1 }
119
+ );
120
+ class N extends He {
121
+ static async getProjectByIdOrSlug(e) {
122
+ return N.findOne({
123
+ where: {
124
+ [We.or]: [{ id: e }, { slug: e }]
125
+ }
126
+ });
127
+ }
128
+ }
129
+ N.init(
130
+ {
131
+ id: {
132
+ type: k.UUID,
133
+ defaultValue: k.UUIDV4,
134
+ primaryKey: !0
135
+ },
136
+ name: {
137
+ type: k.STRING,
138
+ allowNull: !1
139
+ },
140
+ description: k.TEXT,
141
+ createdAt: k.DATE,
142
+ updatedAt: k.DATE,
143
+ createdBy: {
144
+ type: k.STRING,
145
+ allowNull: !1
146
+ },
147
+ updatedBy: {
148
+ type: k.STRING,
149
+ allowNull: !1
150
+ },
151
+ slug: k.STRING,
152
+ icon: k.STRING,
153
+ pinnedAt: k.DATE,
154
+ useAllResources: k.BOOLEAN,
155
+ npmSecret: k.STRING,
156
+ relatedBlocklets: {
157
+ type: k.JSON,
158
+ allowNull: !1,
159
+ defaultValue: {},
160
+ get() {
161
+ const t = this.getDataValue("relatedBlocklets");
162
+ try {
163
+ return t ? JSON.parse(t) : {};
164
+ } catch (e) {
165
+ return f.error("Failed to parse relatedBlocklets", { error: e, rawValue: t }), {};
166
+ }
167
+ },
168
+ set(t) {
169
+ try {
170
+ this.setDataValue("relatedBlocklets", t ? JSON.stringify(t) : "{}");
171
+ } catch (e) {
172
+ f.error("Failed to set relatedBlocklets", { error: e, value: t }), this.setDataValue("relatedBlocklets", "{}");
173
+ }
174
+ }
175
+ },
176
+ productionState: {
177
+ type: k.JSON,
178
+ allowNull: !1,
179
+ defaultValue: {},
180
+ get() {
181
+ const t = this.getDataValue("productionState");
182
+ try {
183
+ return t ? JSON.parse(t) : {};
184
+ } catch (e) {
185
+ return f.error("Failed to parse productionState", { error: e, rawValue: t }), {};
186
+ }
187
+ },
188
+ set(t) {
189
+ try {
190
+ this.setDataValue("productionState", t ? JSON.stringify(t) : "{}");
191
+ } catch (e) {
192
+ f.error("Failed to set productionState", { error: e, value: t }), this.setDataValue("productionState", "{}");
193
+ }
194
+ }
195
+ }
196
+ },
197
+ { sequelize: U, paranoid: !0 }
198
+ );
199
+ N.hasMany(Oe, {
200
+ foreignKey: "projectId",
201
+ as: "components"
202
+ });
203
+ const no = eo, ro = to, ne = 30 * 24 * 60 * 60 * 1e3, ao = 24 * 60 * 60 * 1e3, qe = async (t = "") => {
204
+ const e = P(no, t);
205
+ try {
206
+ if (!(await M.stat(e)).isDirectory())
207
+ throw new Error(`${e} is not a directory`);
208
+ } catch {
209
+ await M.mkdir(e, { recursive: !0 });
210
+ }
211
+ return e;
212
+ }, Le = (t, ...e) => t.keyGenerator ? t.keyGenerator(...e) : JSON.stringify([t.subdir || "", ...e]), io = (t, e) => {
213
+ const o = bt("md5").update(e).digest("hex");
214
+ return P(t, `${ro}-${o}.json`);
215
+ }, co = async (t = "") => {
216
+ const e = await qe(t), o = Date.now();
217
+ try {
218
+ const s = await M.readdir(e);
219
+ await Promise.all(
220
+ s.filter((n) => n.endsWith(".json")).map(async (n) => {
221
+ const r = P(e, n);
222
+ try {
223
+ const c = await M.readFile(r, "utf-8"), a = JSON.parse(c);
224
+ a.createdAt && o - a.createdAt > ne && await M.unlink(r);
225
+ } catch {
226
+ try {
227
+ const a = await M.stat(r);
228
+ o - a.mtimeMs > ne && await M.unlink(r);
229
+ } catch {
230
+ }
231
+ }
232
+ })
233
+ );
234
+ } catch (s) {
235
+ console.error(`Failed to cleanup cache in ${e}:`, s);
236
+ }
237
+ }, po = (() => {
238
+ const t = /* @__PURE__ */ new Set();
239
+ return setInterval(async () => {
240
+ await Promise.all(Array.from(t).map((s) => co(s)));
241
+ }, ao).unref(), (s) => {
242
+ t.add(s);
243
+ };
244
+ })();
245
+ function ue(t, e) {
246
+ return e.subdir && po(e.subdir), gt(
247
+ async (...s) => {
248
+ const n = await qe(e.subdir || ""), r = Le(e, ...s), c = io(n, r);
249
+ try {
250
+ const a = await M.readFile(c, "utf-8"), { value: l, createdAt: d } = JSON.parse(a);
251
+ if (d && Date.now() - d > ne)
252
+ throw await M.unlink(c).catch(() => {
253
+ }), new Error("Cache expired");
254
+ return l;
255
+ } catch {
256
+ const l = await t(...s), d = JSON.stringify({ value: l, createdAt: Date.now() });
257
+ return M.writeFile(c, d, "utf-8").catch((I) => {
258
+ console.error("Failed to write fs cache:", I);
259
+ }), l;
260
+ }
261
+ },
262
+ {
263
+ keyGenerator: (...s) => Le(e, ...s),
264
+ lruOptions: e.lruOptions || {
265
+ max: 100,
266
+ ttl: ne
267
+ }
268
+ }
269
+ );
270
+ }
271
+ const Qe = async () => await import("typescript"), lo = async () => await import("esbuild"), uo = async () => (await import("postcss")).default, fo = async () => (await import("tailwindcss")).default, mo = async () => (await import("autoprefixer")).default, ho = async (t, { componentId: e }) => {
272
+ const o = `@tailwind components;
273
+ @tailwind utilities;
274
+ `, s = `.CustomComponent_${e}`, n = await uo(), r = await fo(), c = await mo();
275
+ return (await n([
276
+ r({ content: [{ raw: t, extension: "tsx" }] }),
277
+ c({
278
+ overrideBrowserslist: ["> 1%", "last 2 versions"],
279
+ stats: {}
280
+ }),
281
+ (l) => {
282
+ l.walkRules((d) => {
283
+ d.selectors = d.selectors.map((I) => I.replace(/\.(.+)/g, `${s}.$1,${s} .$1`));
284
+ });
285
+ }
286
+ // FIXME: cssnano use browserslist, it is not working with the fs isolation
287
+ // cssnano({ preset: 'default' }),
288
+ ]).process(o)).css;
289
+ }, go = async (t, { componentId: e }) => {
290
+ const o = await ho(t, { componentId: e });
291
+ return `export const __PagesKit_CSS__ = ${JSON.stringify(o)};
292
+
293
+ ${t}
294
+ `;
295
+ }, Ne = ue(
296
+ async (t, e) => {
297
+ const o = await Qe();
298
+ let s = o.transpileModule(t, {
299
+ compilerOptions: {
300
+ jsx: o.JsxEmit.React,
301
+ target: o.ScriptTarget.ES2016,
302
+ module: o.ModuleKind.ESNext
303
+ },
304
+ transformers: {
305
+ before: [Dt(o)]
306
+ }
307
+ }).outputText;
308
+ if (e.tailwind && (s = await go(s, { componentId: e.componentId })), e.module === Ie.ESM) return s;
309
+ const n = o.transpileModule(s, {
310
+ compilerOptions: {
311
+ jsx: o.JsxEmit.React,
312
+ target: o.ScriptTarget.ES2016,
313
+ module: o.ModuleKind.CommonJS,
314
+ moduleResolution: o.ModuleResolutionKind.Node16
315
+ }
316
+ }).outputText;
317
+ return e.module === Ie.CJS ? n : wo(e.moduleName, n);
318
+ },
319
+ {
320
+ subdir: "transpileModule"
321
+ }
322
+ ), yo = async (t, e) => {
323
+ const { build: o } = await lo(), n = (await o({
324
+ entryPoints: ["index.tsx"],
325
+ external: Object.keys(Ee),
326
+ format: "esm",
327
+ target: "esnext",
328
+ bundle: !0,
329
+ write: !1,
330
+ plugins: [
331
+ {
332
+ name: "vfs",
333
+ setup(l) {
334
+ let d = null;
335
+ l.onResolve({ filter: /.*/ }, (I) => I.path === "index.tsx" ? { path: "index.tsx", namespace: "vfs" } : I.path === "./component" ? { path: "component.tsx", namespace: "vfs" } : null), l.onLoad({ filter: /.*/, namespace: "vfs" }, async (I) => {
336
+ if (I.path === "index.tsx")
337
+ return { contents: `export { ${e} } from './component'`, loader: "tsx" };
338
+ if (I.path === "component.tsx")
339
+ return { contents: t, loader: "tsx" };
340
+ if (kt(I.path)) {
341
+ const h = I.path.split("/").pop();
342
+ if (d || (d = await Qo({ ensureLoaded: !1 })), d?.chunks?.[h])
343
+ try {
344
+ const S = J(d.chunks[h], "utf-8");
345
+ return f.info("get chunk from local file system", h), { contents: S, loader: "tsx" };
346
+ } catch {
347
+ }
348
+ }
349
+ return null;
350
+ });
351
+ }
352
+ }
353
+ ]
354
+ })).outputFiles?.[0]?.contents;
355
+ if (!n) throw new Error("Failed to build server code");
356
+ const r = Buffer.from(n).toString(), c = await Qe();
357
+ return c.transpileModule(r, {
358
+ compilerOptions: { module: c.ModuleKind.ESNext, target: c.ScriptTarget.ES2020 }
359
+ }).outputText;
360
+ }, So = (t, e) => new RegExp(
361
+ `export\\s+\\{[^}]*(?:\\w+\\s+as\\s+${e}\\b|\\b${e}\\b)[^}]*\\}`,
362
+ "m"
363
+ ).test(t) ? t : void 0, Xe = ue(
364
+ async (t, e) => {
365
+ const o = await yo(t, e);
366
+ return So(o, e);
367
+ },
368
+ {
369
+ subdir: "extractExportValueSchema"
370
+ }
371
+ ), wo = (t, e) => `// GENERATED FILE. DO NOT EDIT.
372
+ var ${t} = async function () {
373
+
374
+ const exports = {};
375
+ let moduleExports = null;
376
+
377
+ // add commonjs module compatibility layer
378
+ const module = { exports: moduleExports };
379
+
380
+ // execute component code
381
+ ${e}
382
+
383
+ // handle possible module.exports
384
+ if (module.exports && module.exports !== moduleExports) {
385
+ // if module.exports is used, use it first
386
+ return typeof module.exports === 'object' ? module.exports : { default: module.exports };
387
+ }
388
+
389
+ // ensure a default export
390
+ if (!('default' in exports) && Object.keys(exports).length === 0) {
391
+ // module has no exports, return null to indicate invalid
392
+ return null;
393
+ }
394
+
395
+ return exports;
396
+ };
397
+ `, Ze = async () => {
398
+ const { Sandbox: t } = await import("@blocklet/quickjs");
399
+ return t;
400
+ };
401
+ function Io(t) {
402
+ return t?.type === "react-component";
403
+ }
404
+ const q = new le({
405
+ max: 100,
406
+ ttl: 1e3 * 60 * 60 * 24
407
+ // 24 hours
408
+ }), Eo = 60 * 60, _e = 10;
409
+ function bo(t) {
410
+ f.info("clear preload components cache", { cacheKey: t }), q.delete(t);
411
+ }
412
+ function Po(t) {
413
+ for (const e of q.keys())
414
+ e.includes(t) && (f.info("clear preload components cache", { cacheKey: e }), bo(e));
415
+ }
416
+ function Ao({
417
+ mode: t,
418
+ instanceId: e,
419
+ componentId: o,
420
+ locale: s
421
+ }) {
422
+ return ["getPreloadComponents", t, e, o, s].join("-");
423
+ }
424
+ async function Us({
425
+ mode: t,
426
+ req: e,
427
+ state: o,
428
+ locale: s,
429
+ instances: n,
430
+ module: r
431
+ }) {
432
+ const {
433
+ supportedLocales: c,
434
+ config: { defaultLocale: a }
435
+ } = o;
436
+ if (!a) return null;
437
+ const l = (await Promise.all(
438
+ n.map(async (p) => {
439
+ try {
440
+ const i = Ao({
441
+ mode: t,
442
+ instanceId: p.id,
443
+ componentId: p.componentId,
444
+ locale: s
445
+ });
446
+ if (t !== "draft" && p.useCache && q.has(i))
447
+ return f.info(`get preload component from cache: ${i}`), q.get(i);
448
+ const y = re({ state: o, componentId: p.componentId });
449
+ if (!y) return null;
450
+ const A = await Co({
451
+ req: e,
452
+ state: o,
453
+ componentId: y.id,
454
+ locale: s,
455
+ defaultLocale: a,
456
+ properties: p.properties
457
+ });
458
+ if (!A) return null;
459
+ const g = { instanceId: p.id, preload: A };
460
+ if (t !== "draft" && p.useCache) {
461
+ let m = Eo;
462
+ p.cacheDuration && (m = p.cacheDuration), f.info(`set preload component to cache(${m}s): ${i}`), q.set(i, g, {
463
+ ttl: m * 1e3
464
+ });
465
+ }
466
+ return g;
467
+ } catch (i) {
468
+ return f.error("get preload component error", { instanceId: p.id, componentId: p.componentId }, { error: i }), null;
469
+ }
470
+ })
471
+ )).filter((p) => !!p), d = Object.values(
472
+ l.reduce((p, i) => ({ ...p, ...i.preload.components }), {})
473
+ );
474
+ async function I() {
475
+ const p = await Promise.all(
476
+ d.map(async (i) => {
477
+ const y = ft({ componentId: i.component.id }), A = r === Ie.ESM ? {
478
+ module: r,
479
+ script: await Ne(i.script, {
480
+ componentId: i.component.id,
481
+ module: r,
482
+ tailwind: t !== "draft"
483
+ })
484
+ } : {
485
+ module: r,
486
+ script: await Ne(i.script, {
487
+ componentId: i.component.id,
488
+ module: r,
489
+ moduleName: y,
490
+ tailwind: t !== "draft"
491
+ }),
492
+ moduleName: y
493
+ };
494
+ return [i.component.id, { component: i.component, script: A }];
495
+ })
496
+ );
497
+ return Object.fromEntries(p);
498
+ }
499
+ const h = await I();
500
+ return {
501
+ config: { defaultLocale: a, supportedLocales: c },
502
+ components: h,
503
+ instances: l.map((p) => ({
504
+ id: p.instanceId,
505
+ componentId: p.preload.component.id,
506
+ locales: { [p.preload.locale]: { props: p.preload.props } }
507
+ }))
508
+ };
509
+ }
510
+ async function Co({
511
+ req: t,
512
+ state: e,
513
+ componentId: o,
514
+ locale: s,
515
+ defaultLocale: n,
516
+ properties: r
517
+ }) {
518
+ const { supportedLocales: c } = e, a = re({ state: e, componentId: o });
519
+ if (!a) return null;
520
+ const l = c.some((I) => I.locale === s) ? s : n;
521
+ if (!l) return null;
522
+ const d = await et({ req: t, state: e, componentId: o, locale: l, defaultLocale: n, properties: r });
523
+ return d ? {
524
+ component: a,
525
+ ...d
526
+ } : null;
527
+ }
528
+ const Oo = 20;
529
+ async function et({
530
+ req: t,
531
+ depth: e = 0,
532
+ state: o,
533
+ componentId: s,
534
+ locale: n,
535
+ defaultLocale: r,
536
+ properties: c
537
+ }) {
538
+ if (e > Oo) throw new RangeError("max component depth exceeded");
539
+ const a = vo({ state: o, componentId: s, properties: c, locale: n });
540
+ if (!a) return null;
541
+ const { props: l, component: d } = a, I = {
542
+ locale: n || r,
543
+ components: { [a.component.id]: { component: a.component, script: a.script } },
544
+ props: { ...l }
545
+ };
546
+ try {
547
+ const h = Io(d.renderer) ? d.renderer.getServerSideProps : void 0, S = await To({ ...a, req: t, serverSideProps: h });
548
+ S?.props && Object.assign(I.props, S.props);
549
+ } catch (h) {
550
+ f.error("preload data at server side error", { componentId: s, name: a.component.name }, { error: h });
551
+ }
552
+ return await Promise.all(
553
+ Object.entries(l).map(async ([h, S]) => {
554
+ if (S?.type === ke) {
555
+ const p = await et({
556
+ req: t,
557
+ depth: e + 1,
558
+ state: o,
559
+ componentId: S.componentId,
560
+ locale: n,
561
+ defaultLocale: r,
562
+ properties: S.properties
563
+ });
564
+ p && (Object.assign(I.components, p.components), Object.assign(I.props, {
565
+ [h]: {
566
+ type: ke,
567
+ componentId: S.componentId,
568
+ props: p.props
569
+ }
570
+ }));
571
+ }
572
+ })
573
+ ), I;
574
+ }
575
+ function vo({
576
+ state: t,
577
+ componentId: e,
578
+ locale: o,
579
+ properties: s
580
+ }) {
581
+ const n = re({ state: t, componentId: e });
582
+ if (!n) return null;
583
+ const r = mt({
584
+ componentId: e,
585
+ getComponent: (c) => re({ state: t, componentId: c }),
586
+ locale: o,
587
+ defaultLocale: t.config.defaultLocale,
588
+ properties: s
589
+ });
590
+ return r ? { component: n, script: r.script, props: { locale: o, ...r.props } } : null;
591
+ }
592
+ function re({ state: t, componentId: e }) {
593
+ return t.components[e]?.data ?? t.resources.components?.[e]?.component;
594
+ }
595
+ async function To({
596
+ component: t,
597
+ script: e,
598
+ props: o,
599
+ req: s,
600
+ serverSideProps: n
601
+ }) {
602
+ if (!n && !e?.includes("getServerSideProps"))
603
+ return null;
604
+ const r = n ?? await Xe(e, "getServerSideProps");
605
+ if (!r) return null;
606
+ const a = (r.match(/export\s*{\s*(\w+)\s+as\s+getServerSideProps\s*}/) || r.match(/export\s*{\s*getServerSideProps\s*}/))?.[1] || "getServerSideProps", l = new Promise((h) => {
607
+ setTimeout(() => {
608
+ h({});
609
+ }, _e * 1e3);
610
+ }), d = await Ze();
611
+ return await Promise.race([
612
+ l,
613
+ d.callFunction({
614
+ code: `${r}
615
+
616
+ export async function getServerSidePropsWrapper(props) {
617
+ const { location, fetch, props: componentProps } = props;
618
+ // 使用局部变量而不是全局变量
619
+ const originalLocation = typeof window !== 'undefined' ? window.location : undefined;
620
+ const originalFetch = globalThis.fetch;
621
+
622
+ try {
623
+ globalThis.location = location;
624
+ globalThis.fetch = fetch;
625
+ return await ${a}(componentProps);
626
+ } finally {
627
+ // 清理全局状态
628
+ if (originalLocation) globalThis.location = originalLocation;
629
+ if (originalFetch) globalThis.fetch = originalFetch;
630
+ }
631
+ }`,
632
+ filename: `${t.name || t.id}.js`,
633
+ moduleLoader: (h) => {
634
+ if (h === "@blocklet/pages-kit/builtin/utils")
635
+ return ` const { joinURL, withQuery, getQuery, getComponentMountPoint } = globalThis
636
+ export { joinURL, withQuery, getQuery, getComponentMountPoint }
637
+ `;
638
+ if (h === "@blocklet/pages-kit/builtin/dayjs")
639
+ return ge.dayjs;
640
+ if (h in ge)
641
+ return ge[h];
642
+ if (h in Ee) {
643
+ const S = Ee[h];
644
+ return Pe(S) ? void 0 : S;
645
+ }
646
+ },
647
+ global: {
648
+ console: {
649
+ // NOTE: do not return logger.xxx result, it will cause memory leak
650
+ // eslint-disable-next-line prettier/prettier
651
+ log: (...h) => {
652
+ f.info(...h);
653
+ },
654
+ warn: (...h) => {
655
+ f.warn(...h);
656
+ },
657
+ error: (...h) => {
658
+ f.error(...h);
659
+ }
660
+ },
661
+ getComponentMountPoint: dt,
662
+ joinURL: V,
663
+ withQuery: It,
664
+ getQuery: wt
665
+ },
666
+ functionName: "getServerSidePropsWrapper",
667
+ args: [
668
+ {
669
+ // NOTE: IMPORTANT! place location and fetch (has side effect) at the args not global
670
+ // because the global is shared between all runtime and just init once
671
+ location: { href: V(Et(s.hostname), s.originalUrl) },
672
+ fetch: (h, { ...S } = {}) => {
673
+ const p = typeof h == "string" && h.startsWith("/") ? V(E.env.appUrl, h) : h;
674
+ if (typeof p == "string" && De(p).host === De(E.env.appUrl).host) {
675
+ const i = s.get("cookie");
676
+ if (i) {
677
+ const y = new St(S.headers);
678
+ y.set("cookie", i), S.headers = y;
679
+ }
680
+ }
681
+ return yt(p, {
682
+ ...S,
683
+ timeout: _e * 1e3
684
+ }).then((i) => ({
685
+ ok: i.ok,
686
+ status: i.status,
687
+ statusText: i.statusText,
688
+ headers: Object.fromEntries(i.headers.entries()),
689
+ json: () => i.json()
690
+ }));
691
+ },
692
+ props: o
693
+ }
694
+ ]
695
+ })
696
+ ]);
697
+ }
698
+ const ko = ue(
699
+ async (t, e, o, s) => {
700
+ if (!t?.includes(e) && !s)
701
+ return null;
702
+ const n = s ?? await Xe(t, e);
703
+ if (n)
704
+ try {
705
+ return await (await Ze()).callFunction({
706
+ code: `
707
+ ${n}
708
+
709
+ export function get${e}SchemaWrapper() {
710
+ return ${e};
711
+ }
712
+ `,
713
+ filename: `${o}.js`,
714
+ functionName: `get${e}SchemaWrapper`
715
+ });
716
+ } catch (r) {
717
+ return f.error(`获取 ${e} 失败`, { componentId: o, error: r }), null;
718
+ }
719
+ return null;
720
+ },
721
+ {
722
+ subdir: "getExportSchemaValueFromCode"
723
+ }
724
+ ), Do = "z8iZiDFg3vkkrPwsiba1TLXy3H9XHzFERsP8o", Ue = "page", Fe = "trigger-reload-project-resource", tt = Do, Ro = "z2qa7BQdkEb3TwYyEYC1psK6uvmGnHSUHt5RM";
725
+ function ae(t) {
726
+ t.observeDeep((e) => {
727
+ e.some((o) => o.changes.keys.has("updatedAt") || o.changes.keys.has("publishedAt")) || t.set("updatedAt", (/* @__PURE__ */ new Date()).toISOString());
728
+ });
729
+ }
730
+ function ot() {
731
+ return Pt(P(E.env.dataDir, "tmp-"));
732
+ }
733
+ function ie(t, e, o = []) {
734
+ return Array.isArray(t) ? t.flatMap((s, n) => ie(s, e, [...o, n])) : typeof t == "object" ? t === null ? [] : Object.entries(t).flatMap(([s, n]) => ie(n, e, [...o, s])) : e(t) ? [o] : [];
735
+ }
736
+ function R(t) {
737
+ return t.filter((e) => e != null);
738
+ }
739
+ function xo(t) {
740
+ t.pages && Object.keys(t.pages).forEach((o) => {
741
+ const s = z(t.pages[o]);
742
+ s && s instanceof _.Map && ae(s);
743
+ });
744
+ const e = z(t.pages);
745
+ e && e instanceof _.Map && e.observe((o) => {
746
+ o.changes.keys.forEach((s, n) => {
747
+ if (s.action === "add") {
748
+ const r = z(t.pages[n]);
749
+ r && r instanceof _.Map && ae(r);
750
+ }
751
+ });
752
+ });
753
+ }
754
+ function jo(t) {
755
+ t.routes && Object.keys(t.routes).forEach((o) => {
756
+ const s = z(t.routes?.[o]);
757
+ s && s instanceof _.Map && ae(s);
758
+ });
759
+ const e = z(t.routes);
760
+ e && e instanceof _.Map && e.observe((o) => {
761
+ o.changes.keys.forEach((s, n) => {
762
+ if (s.action === "add") {
763
+ const r = z(t.routes?.[n]);
764
+ r && r instanceof _.Map && ae(r);
765
+ }
766
+ });
767
+ });
768
+ }
769
+ function $o(t, e) {
770
+ for (const o of e || Object.keys(t.routes || {})) {
771
+ let s = o, n = [];
772
+ if (o.includes("-")) {
773
+ const [r, ...c] = o.split("-");
774
+ s = r, n = c || [];
775
+ }
776
+ if (t.routes?.[s] !== void 0) {
777
+ t.routes[s].publishedAt = (/* @__PURE__ */ new Date()).toISOString();
778
+ const r = t.routes[s];
779
+ if (!r || !r.params || r.params.length === 0)
780
+ continue;
781
+ if (o.includes("-") && n.length > 0) {
782
+ const c = Lt(n, r);
783
+ c && (c.publishedAt = (/* @__PURE__ */ new Date()).toISOString());
784
+ }
785
+ if (!e) {
786
+ const c = Ae({
787
+ basePath: r.path,
788
+ params: r.params,
789
+ routeId: r.id,
790
+ paramsOptions: r.paramsOptions,
791
+ currentIndex: 0,
792
+ currentParams: [],
793
+ currentOptionIds: [],
794
+ result: []
795
+ });
796
+ for (const a of c)
797
+ a.routeMetaData ??= {}, a.routeMetaData.publishedAt = (/* @__PURE__ */ new Date()).toISOString();
798
+ }
799
+ }
800
+ }
801
+ }
802
+ function Se({
803
+ page: t,
804
+ route: e,
805
+ state: o,
806
+ routeId: s,
807
+ routePathInfo: n
808
+ }) {
809
+ f.info(
810
+ `Executing datasource data assembly, routeId: ${s}, routePathInfo: ${JSON.stringify(n)}`
811
+ );
812
+ const r = {
813
+ ...Nt(t),
814
+ id: s,
815
+ slug: n?.path ?? e.path,
816
+ createdAt: e.createdAt,
817
+ updatedAt: n?.routeMetaData?.updatedAt ?? e.updatedAt,
818
+ publishedAt: n?.routeMetaData?.publishedAt ?? e.publishedAt,
819
+ isPublic: (n?.routeMetaData?.isPublic ?? e.isPublic) && e.isPublic
820
+ };
821
+ for (const c of o.supportedLocales) {
822
+ if (e.dataSource) {
823
+ let a = e.id;
824
+ n && (a = n.paramOptionIds.join("-"));
825
+ const l = e.dataSource.pathDataMappings?.[a]?.dataCache?.[c.locale] ?? e.dataSource.pathDataMappings?.[a]?.dataCache?.[o.config.defaultLocale || "en"];
826
+ if (!l)
827
+ continue;
828
+ Mt(r, o, c.locale, l);
829
+ }
830
+ n && n.routeMetaData && (n.routeMetaData.publishedAt = (/* @__PURE__ */ new Date()).toISOString());
831
+ }
832
+ return r;
833
+ }
834
+ const H = new le({
835
+ max: 100,
836
+ ttl: 10 * 60 * 1e3
837
+ // 10 minutes
838
+ });
839
+ function Mo(t, e = []) {
840
+ let o = 0;
841
+ const s = Array.from(H.keys()), n = [];
842
+ for (const r of t) {
843
+ n.push(`page-html:prod:${r}:lang-path=none`);
844
+ for (const c of e)
845
+ n.push(`page-html:prod:/${c}${r}:lang-path=${c}`);
846
+ }
847
+ for (const r of s) {
848
+ const c = r.split(":lang-path=")[0] || "";
849
+ for (const a of n) {
850
+ const d = (a.split(":lang-path=")[0] || "").replace(/\/:[^/]+/g, "");
851
+ if (c.startsWith(d)) {
852
+ H.delete(r), o++, f.info(`[Cache CLEAR] key: ${r}`);
853
+ break;
854
+ }
855
+ }
856
+ }
857
+ return f.info(`[Cache CLEAR] cleared ${o} entries for patterns:`, n), o;
858
+ }
859
+ function Lo({
860
+ projectId: t,
861
+ projectSlug: e,
862
+ supportedLocales: o = []
863
+ }) {
864
+ let s = 0;
865
+ const n = Array.from(H.keys()), r = [];
866
+ r.push(`page-html:prod:/${t}`), e && e !== t && r.push(`page-html:prod:/${e}`);
867
+ for (const c of o)
868
+ r.push(`page-html:prod:/${c}/${t}`), e && e !== t && (e !== "/" ? r.push(`page-html:prod:/${c}/${e}`) : r.push(`page-html:prod:/${c}`));
869
+ for (const c of n)
870
+ for (const a of r)
871
+ if (c.startsWith(a)) {
872
+ H.delete(c), s++, f.info(`[Cache CLEAR PROJECT] key: ${c}`);
873
+ break;
874
+ }
875
+ return f.info(
876
+ `[Cache CLEAR PROJECT] cleared ${s} entries for project ${t}${e ? ` (slug: ${e})` : ""}`
877
+ ), s;
878
+ }
879
+ function No() {
880
+ const t = H.size;
881
+ return H.clear(), f.info(`[Cache CLEAR ALL] cleared ${t} entries`), t;
882
+ }
883
+ E.events.on(E.Events.envUpdate, No);
884
+ const { uploadToMediaKit: _o } = require("@blocklet/uploader-server"), ve = /^\w+(\w|-|\.)+\w+\.(jpe?g|png|gif|svg|bmp|webp|mp4|m4v|webm)$/, Q = /mediakit:\/\/([a-f0-9]{32}\.(jpe?g|png|gif|svg|bmp|webp|mp4|m4v|webm))/i, Be = /mediakit:\/\/([a-f0-9]{32}\.(jpe?g|png|gif|svg|bmp|webp|mp4|m4v|webm))/gi, Uo = 1e4, Fo = 3e4, Z = 0, we = 1, Bo = 0, Vo = 1, st = E, ee = P(process.env.BLOCKLET_DATA_DIR, "site-state");
885
+ function ce(t) {
886
+ return t?.replace(/\//g, "|") || "";
887
+ }
888
+ function Go() {
889
+ const t = st.env.languages.map((o) => ({ locale: o.code, name: o.name })), e = t[0]?.locale;
890
+ return {
891
+ pageIds: [],
892
+ pages: {},
893
+ routeIds: [],
894
+ routes: {},
895
+ dataSourceIds: [],
896
+ dataSources: {},
897
+ components: {},
898
+ supportedLocales: t,
899
+ config: { defaultLocale: e },
900
+ resources: {}
901
+ };
902
+ }
903
+ class v extends _.Doc {
904
+ constructor(e) {
905
+ super(), this.options = e, L(this.draftYjsFilePath) && _.applyUpdate(this, J(this.draftYjsFilePath)), this.syncedStore = Ut(
906
+ $t(
907
+ {
908
+ pages: {},
909
+ pageIds: [],
910
+ components: {},
911
+ supportedLocales: [],
912
+ config: {},
913
+ resources: {},
914
+ routeIds: [],
915
+ routes: {},
916
+ dataSourceIds: [],
917
+ dataSources: {}
918
+ },
919
+ this
920
+ )
921
+ ), this.initObserver(), this.on("update", this.updateHandler), this.awareness = new Ht(this), this.awareness.on("update", this.awarenessChangeHandler), this.ensureDataStructure();
922
+ }
923
+ // 延迟释放时间:5 分钟
924
+ static RELEASE_DELAY = 5 * 60 * 1e3;
925
+ // 定期检查间隔:2 小时
926
+ static PERIODIC_CHECK_INTERVAL = 2 * 60 * 60 * 1e3;
927
+ // 2 hours
928
+ static sharedInstances = {};
929
+ static pageUrlMapCache = new le({
930
+ max: 100,
931
+ ttl: 1e3 * 60 * 60 * 24
932
+ // 1 day
933
+ });
934
+ // 定期检查定时器
935
+ static periodicCheckTimer;
936
+ // safe delete project state dir
937
+ static safeDeleteProjectStateDir(e) {
938
+ if (!e)
939
+ throw new Error("Should provide project context");
940
+ try {
941
+ const o = P(ee, e), s = P(ee, `@del-${e}`);
942
+ Re(o, s);
943
+ } catch (o) {
944
+ f.error("Failed to safe delete project state dir:", o);
945
+ }
946
+ }
947
+ static async getProjectIds() {
948
+ return (await N.findAll({ attributes: ["id"], raw: !0 })).map((e) => e.id);
949
+ }
950
+ /** @deprecated 不再使用这个 getter 了,仅作为兼容性处理,请使用 getProjectIds 代替 */
951
+ static get projectIds() {
952
+ return se("*/", {
953
+ cwd: ee,
954
+ ignore: ["@del-*", "@tmp-*", ".*", "staging", "production", "@backup-*", "undefined"]
955
+ // Ignore temp directories and hidden files
956
+ });
957
+ }
958
+ /** @deprecated 不再使用这个 getter 了,仅作为兼容性处理 */
959
+ static get allShared() {
960
+ return this.projectIds.map((e) => v.shared(e));
961
+ }
962
+ static shared(e) {
963
+ if (!e)
964
+ throw new Error("Should provide project context");
965
+ let o = v.sharedInstances[e];
966
+ return o || (o = new v({
967
+ path: P(ee, e)
968
+ }), v.sharedInstances[e] = o, lt({
969
+ projectId: e,
970
+ pages: de,
971
+ components: fe
972
+ }), o);
973
+ }
974
+ // 轻量级 production 状态获取,不加载 draft 数据
975
+ static async getProductionState(e) {
976
+ return (await N.findByPk(e, {
977
+ attributes: ["productionState"]
978
+ }))?.productionState ?? Go();
979
+ }
980
+ destroy() {
981
+ this.cancelRelease(), this.save({ flush: !0 }), this.conns.forEach((o, s) => this.closeConn(s)), this.awareness.destroy();
982
+ const e = x(this.options.path);
983
+ delete v.sharedInstances[e], super.destroy();
984
+ }
985
+ initObserver() {
986
+ xo(this.syncedStore), jo(this.syncedStore);
987
+ }
988
+ get draftYjsFilePath() {
989
+ return P(this.options.path, "draft.yjs");
990
+ }
991
+ static async getStateByProjectId(e, o) {
992
+ if (o === "draft") {
993
+ const s = v.shared(e);
994
+ return JSON.parse(JSON.stringify(s.syncedStore));
995
+ }
996
+ return v.getProductionState(e);
997
+ }
998
+ async getState(e) {
999
+ if (e === "draft")
1000
+ return JSON.parse(JSON.stringify(this.syncedStore));
1001
+ const o = x(this.options.path);
1002
+ return v.getProductionState(o);
1003
+ }
1004
+ async setState(e, o) {
1005
+ const s = await Ho(o, { exportAssets: !1, includeResources: !0 }), n = this.getPublishDir(e);
1006
+ if (F(j(n), { recursive: !0 }), Je(n, { force: !0, recursive: !0 }), Re(s, n), e === "production") {
1007
+ const r = x(this.options.path);
1008
+ v.pageUrlMapCache.delete(r), await N.update({ productionState: o }, { where: { id: r } });
1009
+ }
1010
+ }
1011
+ getPublishDir(e) {
1012
+ return P(this.options.path, e);
1013
+ }
1014
+ syncedStore;
1015
+ conns = /* @__PURE__ */ new Map();
1016
+ awareness;
1017
+ // 延迟释放定时器
1018
+ releaseTimer;
1019
+ awarenessChangeHandler = ({ added: e, updated: o, removed: s }, n) => {
1020
+ const r = e.concat(o, s);
1021
+ if (n !== null) {
1022
+ const l = this.conns.get(n);
1023
+ l && (e.forEach((d) => {
1024
+ l.add(d);
1025
+ }), s.forEach((d) => {
1026
+ l.delete(d);
1027
+ }));
1028
+ }
1029
+ const c = D.createEncoder();
1030
+ D.writeVarUint(c, we), D.writeVarUint8Array(c, $e(this.awareness, r));
1031
+ const a = D.toUint8Array(c);
1032
+ this.conns.forEach((l, d) => this.send(d, a));
1033
+ };
1034
+ updateHandler = (e) => {
1035
+ const o = D.createEncoder();
1036
+ D.writeVarUint(o, Z), qt(o, e);
1037
+ const s = D.toUint8Array(o);
1038
+ this.conns.forEach((n, r) => this.send(r, s));
1039
+ };
1040
+ ensureDataStructure = () => {
1041
+ const { supportedLocales: e, pages: o, pageIds: s, config: n, routes: r, routeIds: c } = this.syncedStore;
1042
+ {
1043
+ const a = new Set(Object.keys(o));
1044
+ let l = 0;
1045
+ for (; l < s.length; ) {
1046
+ const d = s[l];
1047
+ a.has(d) ? (a.delete(d), l++) : s.splice(l, 1);
1048
+ }
1049
+ }
1050
+ {
1051
+ const a = new Set(Object.keys(r));
1052
+ let l = 0;
1053
+ for (; l < c.length; ) {
1054
+ const d = c[l];
1055
+ a.has(d) ? (a.delete(d), l++) : c.splice(l, 1);
1056
+ }
1057
+ }
1058
+ e.splice(0, e.length), e.push(...st.env.languages.map((a) => ({ locale: a.code, name: a.name }))), n.defaultLocale = e[0]?.locale;
1059
+ {
1060
+ let a = 0;
1061
+ const l = /* @__PURE__ */ new Set();
1062
+ for (; a < e.length; ) {
1063
+ const { locale: d } = e[a];
1064
+ l.has(d) ? e.splice(a, 1) : (a++, l.add(d));
1065
+ }
1066
+ }
1067
+ };
1068
+ send = (e, o) => {
1069
+ e.readyState !== Bo && e.readyState !== Vo && this.closeConn(e);
1070
+ try {
1071
+ e.send(o, (s) => {
1072
+ s && this.closeConn(e);
1073
+ });
1074
+ } catch {
1075
+ this.closeConn(e);
1076
+ }
1077
+ };
1078
+ closeConn = (e) => {
1079
+ if (e.removeAllListeners(), this.conns.has(e)) {
1080
+ const o = this.conns.get(e);
1081
+ this.conns.delete(e), o && Wt(this.awareness, Array.from(o), null);
1082
+ }
1083
+ e.close(), this.checkAndScheduleRelease();
1084
+ };
1085
+ // 检查并调度延迟释放
1086
+ checkAndScheduleRelease() {
1087
+ this.conns.size === 0 && this.scheduleRelease();
1088
+ }
1089
+ // 调度延迟释放
1090
+ scheduleRelease() {
1091
+ this.cancelRelease();
1092
+ const e = x(this.options.path);
1093
+ this.releaseTimer = setTimeout(() => {
1094
+ f.info(`[SiteState] releasing instance due to no active connections: ${e}`), this.conns.size === 0 && (this.releaseTimer = void 0, this.destroy());
1095
+ }, v.RELEASE_DELAY), f.info(`[SiteState] scheduled release for project ${e} in ${v.RELEASE_DELAY / 1e3}s`);
1096
+ }
1097
+ // 取消延迟释放
1098
+ cancelRelease() {
1099
+ if (this.releaseTimer) {
1100
+ clearTimeout(this.releaseTimer), this.releaseTimer = void 0;
1101
+ const e = x(this.options.path);
1102
+ f.info(`[SiteState] cancelled scheduled release for project ${e}`);
1103
+ }
1104
+ }
1105
+ autoSave = ze(() => {
1106
+ F(j(this.draftYjsFilePath), { recursive: !0 }), oe(this.draftYjsFilePath, _.encodeStateAsUpdate(this));
1107
+ }, Uo);
1108
+ save = ({ flush: e = !1 } = {}) => {
1109
+ this.autoSave(), e && this.autoSave.flush();
1110
+ };
1111
+ publish = async ({ mode: e, routes: o }) => {
1112
+ const s = await this.getState("draft"), n = await this.getState("production");
1113
+ await Ge(s, n, { routes: o, mergeMode: "replace", deleteRoutes: !0, publishMode: e }), n.config.publishedAt = (/* @__PURE__ */ new Date()).getTime(), $o(this.syncedStore, o), await this.setState(e, n), await this.clearPageCacheForRoutes(o, n);
1114
+ };
1115
+ mergeState = async (e, o) => {
1116
+ const s = JSON.parse(JSON.stringify(o));
1117
+ e.config.fontFamily ??= {};
1118
+ const n = s.config?.fontFamily, r = e.config?.fontFamily;
1119
+ e.config.fontFamily.title = n?.title || r?.title, e.config.fontFamily.description = n?.description || r?.description, await new Promise((c, a) => {
1120
+ this.transact(async () => {
1121
+ try {
1122
+ const l = await Ge(e, o);
1123
+ c(l);
1124
+ } catch (l) {
1125
+ a(l);
1126
+ }
1127
+ });
1128
+ });
1129
+ };
1130
+ clearPageCacheForRoutes = async (e, o) => {
1131
+ const s = x(this.options.path), r = (await N.findByPk(s))?.slug || s;
1132
+ if (f.info(`[SiteState] clearing page cache for project ${s}, routes:`, e || []), !e || e.length === 0) {
1133
+ Lo({
1134
+ projectId: s,
1135
+ projectSlug: r,
1136
+ supportedLocales: o.supportedLocales.map((d) => d.locale)
1137
+ });
1138
+ return;
1139
+ }
1140
+ const c = o.supportedLocales.map((d) => d.locale), a = [], l = e.filter((d) => o.pages[d]);
1141
+ for (const d of l) {
1142
+ const h = o.pages[d].slug;
1143
+ r && r !== s && (r === "/" ? a.push(h) : a.push(`/${r}${h}`)), a.push(`/${s}${h}`);
1144
+ }
1145
+ if (f.info(`[SiteState] clearing page cache for project ${s}, pathPatterns:`, a), a.length > 0) {
1146
+ const d = Mo(a, c);
1147
+ f.info(`[SiteState] cleared ${d} page cache entries for project ${s}, routes:`, e);
1148
+ }
1149
+ };
1150
+ addConnection = (e) => {
1151
+ if (this.conns.has(e))
1152
+ return;
1153
+ this.cancelRelease(), e.binaryType = "arraybuffer", this.conns.set(e, /* @__PURE__ */ new Set()), e.on("message", (n) => this.messageListener(e, new Uint8Array(n)));
1154
+ let o = !0;
1155
+ const s = setInterval(() => {
1156
+ if (!o)
1157
+ this.conns.has(e) && this.closeConn(e), clearInterval(s);
1158
+ else if (this.conns.has(e)) {
1159
+ o = !1;
1160
+ try {
1161
+ e.ping();
1162
+ } catch {
1163
+ this.closeConn(e), clearInterval(s);
1164
+ }
1165
+ }
1166
+ }, Fo);
1167
+ e.on("close", () => {
1168
+ this.closeConn(e), clearInterval(s);
1169
+ }), e.on("pong", () => {
1170
+ o = !0;
1171
+ });
1172
+ {
1173
+ const n = D.createEncoder();
1174
+ D.writeVarUint(n, Z), Qt(n, this), this.send(e, D.toUint8Array(n));
1175
+ const r = this.awareness.getStates();
1176
+ if (r.size > 0) {
1177
+ const c = D.createEncoder();
1178
+ D.writeVarUint(c, we), D.writeVarUint8Array(c, $e(this.awareness, Array.from(r.keys()))), this.send(e, D.toUint8Array(c));
1179
+ }
1180
+ }
1181
+ };
1182
+ messageListener = (e, o) => {
1183
+ try {
1184
+ const s = D.createEncoder(), n = ye.createDecoder(o), r = ye.readVarUint(n);
1185
+ switch (r) {
1186
+ case Z:
1187
+ D.writeVarUint(s, Z), Xt(n, s, this, null), D.length(s) > 1 && (this.ensureDataStructure(), this.send(e, D.toUint8Array(s)));
1188
+ break;
1189
+ case we: {
1190
+ Yt(this.awareness, ye.readVarUint8Array(n), e);
1191
+ break;
1192
+ }
1193
+ default:
1194
+ f.warn(`Unsupported messageType ${r}`);
1195
+ }
1196
+ } catch (s) {
1197
+ f.error(s);
1198
+ }
1199
+ this.save();
1200
+ };
1201
+ // 这个方法还是需要动态的,因为可能会动态修改 projectSlug、语言之类的
1202
+ static async pageUrlMap(e, o) {
1203
+ let s = [];
1204
+ o ? s = [o] : s = await this.getProjectIds();
1205
+ let n = {};
1206
+ if (e === "production" && s?.length) {
1207
+ const r = new Map(s.map((c) => [c, !0]));
1208
+ for (const c of s) {
1209
+ const a = v.pageUrlMapCache.get(c);
1210
+ a && (n = { ...n, ...a }, r.delete(c));
1211
+ }
1212
+ s = Array.from(r.keys());
1213
+ }
1214
+ if (s?.length) {
1215
+ const r = await N.findAll({
1216
+ where: {
1217
+ id: {
1218
+ [We.in]: s
1219
+ }
1220
+ }
1221
+ });
1222
+ await Promise.all(
1223
+ r.map(async (c) => {
1224
+ const a = c.id, l = c.slug || a, d = {}, I = e === "production" && c?.productionState ? c.productionState : await v.getStateByProjectId(c.id, e), h = Bt(
1225
+ E.env.languages.map((p) => p.code),
1226
+ I.supportedLocales.map((p) => p.locale)
1227
+ ), S = (p, i) => {
1228
+ l && (d[V("/", l, p)] = {
1229
+ ...i,
1230
+ shouldRedirect: !0,
1231
+ mainPage: !0
1232
+ }), d[V("/", a, p)] = {
1233
+ ...i,
1234
+ shouldRedirect: !0,
1235
+ mainPage: !0
1236
+ };
1237
+ for (const y of h) {
1238
+ const A = { ...i, locale: y };
1239
+ d[V("/", y, a, p)] = A, l && (d[V("/", y, l, p)] = A);
1240
+ }
1241
+ };
1242
+ if (e === "draft")
1243
+ for (const p of I.routeIds || []) {
1244
+ const i = I?.routes?.[p];
1245
+ if (!i) continue;
1246
+ if (i.params && i.params.length > 0) {
1247
+ const g = Ae({
1248
+ basePath: i.path,
1249
+ params: i.params,
1250
+ routeId: i.id,
1251
+ paramsOptions: i.paramsOptions,
1252
+ currentIndex: 0,
1253
+ currentParams: [],
1254
+ currentOptionIds: [],
1255
+ result: []
1256
+ });
1257
+ for (const m of g) {
1258
+ const w = m.path, C = {
1259
+ projectId: a,
1260
+ projectSlug: l,
1261
+ pageSlug: w,
1262
+ pageId: i.displayTemplateId || "",
1263
+ routeId: p,
1264
+ // default locale
1265
+ defaultLocale: h?.[0],
1266
+ locales: h,
1267
+ publishedAt: I.config.publishedAt,
1268
+ isPublic: i.isPublic && m?.routeMetaData?.isPublic
1269
+ };
1270
+ S(w, C);
1271
+ }
1272
+ }
1273
+ const y = i.path, A = {
1274
+ projectId: a,
1275
+ projectSlug: l,
1276
+ pageSlug: y,
1277
+ pageId: i.displayTemplateId || "",
1278
+ routeId: p,
1279
+ // default locale
1280
+ defaultLocale: h?.[0],
1281
+ locales: h,
1282
+ publishedAt: I.config.publishedAt,
1283
+ isPublic: i.isPublic
1284
+ };
1285
+ S(y, A);
1286
+ }
1287
+ for (const p of I.pageIds) {
1288
+ const i = I.pages[p];
1289
+ if (!i || e === "production" && !i.isPublic)
1290
+ continue;
1291
+ const y = i.slug, A = c.slug || a, g = {
1292
+ projectId: a,
1293
+ projectSlug: A,
1294
+ pageSlug: y,
1295
+ pageId: p,
1296
+ // default locale
1297
+ defaultLocale: h?.[0],
1298
+ locales: h,
1299
+ publishedAt: I.config.publishedAt,
1300
+ isPublic: i.isPublic,
1301
+ templateConfig: i.templateConfig
1302
+ };
1303
+ S(y, g);
1304
+ }
1305
+ e === "production" && v.pageUrlMapCache.set(a, d), n = { ...n, ...d };
1306
+ })
1307
+ );
1308
+ }
1309
+ return n;
1310
+ }
1311
+ getDocumentSize() {
1312
+ return _.encodeStateAsUpdate(this).byteLength;
1313
+ }
1314
+ static getInstancesSizeInfo() {
1315
+ const e = [];
1316
+ for (const [o, s] of Object.entries(v.sharedInstances)) {
1317
+ const n = s.getDocumentSize();
1318
+ e.push({
1319
+ projectId: o,
1320
+ sizeInBytes: n,
1321
+ sizeInMB: `${(n / (1024 * 1024)).toFixed(2)} MB`,
1322
+ activeConnections: s.conns.size
1323
+ });
1324
+ }
1325
+ return e;
1326
+ }
1327
+ // 启动定期检查
1328
+ static startPeriodicCheck() {
1329
+ this.periodicCheckTimer || (this.periodicCheckTimer = setInterval(() => {
1330
+ this.performPeriodicCheck();
1331
+ }, this.PERIODIC_CHECK_INTERVAL), f.info(
1332
+ `[SiteState] periodic check started, interval: ${this.PERIODIC_CHECK_INTERVAL / (60 * 60 * 1e3)} hours`
1333
+ ));
1334
+ }
1335
+ // 停止定期检查
1336
+ static stopPeriodicCheck() {
1337
+ this.periodicCheckTimer && (clearInterval(this.periodicCheckTimer), this.periodicCheckTimer = void 0, f.info("[SiteState] periodic check stopped"));
1338
+ }
1339
+ // 执行定期检查
1340
+ static performPeriodicCheck() {
1341
+ const e = Object.keys(v.sharedInstances).length, o = [], s = [];
1342
+ for (const [n, r] of Object.entries(v.sharedInstances))
1343
+ r.conns.size === 0 ? o.push({ projectId: n, instance: r }) : s.push({ projectId: n, connections: r.conns.size });
1344
+ if (f.info(
1345
+ `[SiteState] periodic check summary: total instances: ${e}, with connections: ${s.length}, without connections: ${o.length}`
1346
+ ), o.length > 0) {
1347
+ f.info(
1348
+ `[SiteState] releasing ${o.length} instances without connections:`,
1349
+ o.map((r) => r.projectId)
1350
+ );
1351
+ let n = 0;
1352
+ for (const { projectId: r, instance: c } of o)
1353
+ try {
1354
+ f.info(`[SiteState] releasing instance due to periodic check: ${r}`), c.destroy(), n++;
1355
+ } catch (a) {
1356
+ f.error(`[SiteState] failed to release instance ${r} during periodic check:`, a);
1357
+ }
1358
+ f.info(
1359
+ `[SiteState] periodic check completed: ${n}/${o.length} instances released successfully`
1360
+ );
1361
+ } else e > 0 ? f.debug("[SiteState] periodic check: all instances have active connections") : f.debug("[SiteState] periodic check: no instances exist");
1362
+ }
1363
+ }
1364
+ async function Jo(t, e, o) {
1365
+ if (!t || !L(t) || !G(t).isFile())
1366
+ return null;
1367
+ let s = o[t];
1368
+ return s || (s = (async () => {
1369
+ try {
1370
+ return (await _o({
1371
+ filePath: t,
1372
+ fileName: e
1373
+ }))?.data?.filename;
1374
+ } catch (n) {
1375
+ return f.error(`Failed to upload asset ${t}:`, n), null;
1376
+ }
1377
+ })(), o[t] = s), s;
1378
+ }
1379
+ const Ko = async (t, e) => {
1380
+ const o = x(t), s = await jt({
1381
+ name: tt,
1382
+ path: V("/uploads", o),
1383
+ responseType: "stream",
1384
+ method: "GET"
1385
+ });
1386
+ if (s.status >= 200 && s.status < 400) {
1387
+ const n = Ot(e);
1388
+ await Jt(s.data, n);
1389
+ } else
1390
+ throw new Error(`download asset failed ${s.status}`);
1391
+ }, zo = async (t, e) => {
1392
+ await Promise.all(
1393
+ t.map(async (o) => {
1394
+ try {
1395
+ await Ko(o, P(e, x(o)));
1396
+ } catch (s) {
1397
+ f.error(`Failed to export assets: ${o}, ${s}`);
1398
+ }
1399
+ })
1400
+ );
1401
+ };
1402
+ function nt(t) {
1403
+ return ve.test(t) ? [t] : Q.test(t) ? (Be.lastIndex = 0, Array.from(t.matchAll(Be)).map((o) => o[1]).filter((o) => !!o)) : [];
1404
+ }
1405
+ async function te(t, e, o) {
1406
+ const { getFilename: s, exportAssets: n } = o, r = P(e, s(t));
1407
+ if (F(j(r), { recursive: !0 }), oe(r, K.stringify(t)), n) {
1408
+ const a = ie(
1409
+ t,
1410
+ (l) => typeof l == "string" && (ve.test(l) || Q.test(l))
1411
+ ).map((l) => {
1412
+ const d = Ce(t, l);
1413
+ return nt(d);
1414
+ }).flat().filter(Boolean);
1415
+ await zo(a, j(r));
1416
+ }
1417
+ }
1418
+ const be = new le({
1419
+ max: 100,
1420
+ ttl: 1 * 60 * 1e3
1421
+ // 1 minute
1422
+ });
1423
+ async function Ve(t, e, o) {
1424
+ const s = ie(
1425
+ t,
1426
+ (a) => typeof a == "string" && (ve.test(a) || Q.test(a))
1427
+ ), n = Vt(2), r = s.map(
1428
+ (a) => n(async () => {
1429
+ try {
1430
+ const l = Ce(t, a), d = nt(l);
1431
+ for (const I of d) {
1432
+ const h = x(I), S = o.getFilePath(I, a), p = S ? `${S}:${h}` : h, i = be.get(p);
1433
+ if (i) {
1434
+ Q.test(l) || je(t, a, i);
1435
+ return;
1436
+ }
1437
+ const y = await Jo(S, h, e);
1438
+ y && (Q.test(l) || je(t, a, y), be.set(p, y));
1439
+ }
1440
+ } catch (l) {
1441
+ f.error(`Failed to process upload for path ${a.join(".")}:`, l.message || l.reason);
1442
+ }
1443
+ })
1444
+ ), c = await Promise.allSettled(r);
1445
+ o.onFinish?.(c);
1446
+ }
1447
+ async function Ho(t, {
1448
+ exportAssets: e,
1449
+ pageIds: o = "all",
1450
+ componentIds: s = "all",
1451
+ rawConfig: n,
1452
+ includeResources: r = !1,
1453
+ routeIds: c = "all"
1454
+ } = {}) {
1455
+ const a = o === "all" ? t.pageIds : o, l = ht({
1456
+ state: t,
1457
+ pageIds: a,
1458
+ componentIds: s === "all" ? Object.keys(t.components) : s
1459
+ }), d = c === "all" ? t.routeIds : c, I = (u) => ({
1460
+ id: u.id,
1461
+ name: u.name,
1462
+ isTemplateSection: u.isTemplateSection ?? !1,
1463
+ templateDescription: u.templateDescription,
1464
+ llmConfig: u.llmConfig,
1465
+ component: u.component,
1466
+ config: u.config,
1467
+ visibility: u.visibility,
1468
+ sections: u?.sectionIds ? R(
1469
+ u?.sectionIds?.map((b) => {
1470
+ const T = u.sections?.[b];
1471
+ return T && I(T);
1472
+ })
1473
+ ) : void 0
1474
+ // 已经废弃,数据在 page.dataSource 中管理
1475
+ // properties: section.locales?.[locale] ?? {},
1476
+ }), h = (u, b) => ({
1477
+ id: u.id,
1478
+ createdAt: u.createdAt,
1479
+ updatedAt: u.updatedAt,
1480
+ publishedAt: u.publishedAt,
1481
+ isPublic: u.isPublic ?? !0,
1482
+ templateConfig: u.templateConfig,
1483
+ meta: u.locales?.[b] ?? {},
1484
+ sections: R(
1485
+ u.sectionIds.map((T) => {
1486
+ const B = u.sections[T];
1487
+ return B && I(B);
1488
+ })
1489
+ ),
1490
+ // 将 dataSource.sectionId.locale 转换为 dataSource.sectionId
1491
+ dataSource: Object.fromEntries(
1492
+ Object.entries(u.dataSource || {}).map(([T, B]) => [T, B?.[b] ?? {}])
1493
+ )
1494
+ }), S = (u) => ({
1495
+ id: u.id,
1496
+ createdAt: u.createdAt,
1497
+ updatedAt: u.updatedAt,
1498
+ publishedAt: u.publishedAt,
1499
+ path: u.path,
1500
+ handler: u.handler,
1501
+ isPublic: u.isPublic ?? !0,
1502
+ params: u.params ?? [],
1503
+ enabledGenerate: u.enabledGenerate ?? !1,
1504
+ displayTemplateId: u.displayTemplateId,
1505
+ dataSource: u.dataSource
1506
+ }), p = R(
1507
+ d.map((u) => {
1508
+ const b = t.routes[u];
1509
+ return b && S(b);
1510
+ })
1511
+ ), i = R(
1512
+ t.supportedLocales.map((u) => u.locale).flatMap(
1513
+ (u) => a.map((b) => {
1514
+ const T = t.pages[b];
1515
+ return T && {
1516
+ locale: u,
1517
+ slug: T.slug,
1518
+ page: h(T, u)
1519
+ };
1520
+ })
1521
+ )
1522
+ ), y = ot(), A = P(y, "pages");
1523
+ F(A, { recursive: !0 });
1524
+ const g = P(y, "components");
1525
+ F(g, { recursive: !0 });
1526
+ const m = P(y, "routes");
1527
+ F(m, { recursive: !0 });
1528
+ for (const { locale: u, slug: b, page: T } of i)
1529
+ await te(T, A, {
1530
+ getFilename: () => `${ce(b) || "index"}.${u}.yml`,
1531
+ exportAssets: e
1532
+ });
1533
+ for (const u of p)
1534
+ await te(u, m, {
1535
+ // getFilename: () => `${sanitizeSlug(route.path)}.yml`,
1536
+ getFilename: () => `${ce(u.path) || "index"}.yml`,
1537
+ exportAssets: e
1538
+ });
1539
+ for (const u of l) {
1540
+ const b = t.components[u]?.data;
1541
+ b && await te(b, g, {
1542
+ getFilename: (T) => `${T.name || "unnamed"}.${T.id}.yml`,
1543
+ exportAssets: e
1544
+ });
1545
+ }
1546
+ const w = P(y, ".blocklet/pages/pages.config.yml");
1547
+ F(j(w), { recursive: !0 });
1548
+ const C = {
1549
+ pages: R(
1550
+ a.map((u) => {
1551
+ const b = t.pages[u];
1552
+ return b && { id: u, slug: b.slug };
1553
+ })
1554
+ ),
1555
+ routes: R(
1556
+ d.map((u) => {
1557
+ const b = t.routes[u];
1558
+ return b && { id: u, path: b.path };
1559
+ })
1560
+ ),
1561
+ components: R(
1562
+ l.map((u) => {
1563
+ const b = t.components[u]?.data;
1564
+ return b && {
1565
+ id: u,
1566
+ name: b.name
1567
+ };
1568
+ })
1569
+ ),
1570
+ ...r ? {
1571
+ resources: {
1572
+ components: R(
1573
+ Object.keys(t.resources?.components || {}).filter((u) => l.includes(u)).map((u) => ({
1574
+ id: u,
1575
+ name: t.resources?.components?.[u]?.component?.name
1576
+ }))
1577
+ )
1578
+ }
1579
+ } : {},
1580
+ supportedLocales: t.supportedLocales,
1581
+ config: t.config
1582
+ };
1583
+ oe(w, K.stringify(C));
1584
+ const O = P(y, "config.source.json");
1585
+ if (n && oe(O, JSON.stringify(n)), r) {
1586
+ const u = P(y, "resources"), b = P(u, "components");
1587
+ F(b, { recursive: !0 });
1588
+ for (const W of Object.keys(t?.resources?.components ?? {}).filter(
1589
+ ($) => l.includes($)
1590
+ )) {
1591
+ const $ = t.resources?.components?.[W]?.component;
1592
+ $ && await te($, b, {
1593
+ getFilename: (Y) => `${Y.name || "unnamed"}.${Y.id}.yml`,
1594
+ exportAssets: e
1595
+ });
1596
+ }
1597
+ const T = P(y, "chunks");
1598
+ F(T, { recursive: !0 });
1599
+ const B = Yo();
1600
+ for (const W of Object.keys(t?.resources?.components ?? {}).filter(
1601
+ ($) => l.includes($)
1602
+ )) {
1603
+ const $ = t.resources?.components?.[W]?.component;
1604
+ if ($ && $.renderer?.type === "react-component") {
1605
+ const Y = $.renderer?.chunks ?? [];
1606
+ if (Y?.length > 0)
1607
+ for (const me of Y) {
1608
+ const Te = P(T, me), he = B?.[me];
1609
+ try {
1610
+ he && L(he) && !L(Te) && At(he, Te);
1611
+ } catch (ut) {
1612
+ f.error(`copy chunk ${me} error`, ut.message);
1613
+ }
1614
+ }
1615
+ }
1616
+ }
1617
+ }
1618
+ return y;
1619
+ }
1620
+ async function Wo(t, { importAssets: e, includeResources: o } = {}) {
1621
+ if (!L(t))
1622
+ return null;
1623
+ let s, n = !1;
1624
+ try {
1625
+ G(t).isDirectory() ? s = t : /\.(tgz|gz|tar)$/.test(t) && (n = !0, s = ot(), await Kt({ file: t, C: s }));
1626
+ const r = se("**/.blocklet/pages/pages.config.yml", { cwd: s, absolute: !0 }).at(0), c = r && P(j(r), "../../pages"), a = r && P(j(r), "../../components"), l = r && P(j(r), "../../routes");
1627
+ if (!r)
1628
+ return null;
1629
+ const d = K.parse(J(r).toString()), I = (g, m, w) => {
1630
+ let C = P(g, `${m}${w ? `.${w}` : ""}.yml`);
1631
+ return (!L(C) || !G(C).isFile()) && (C = P(g, m, `index${w ? `.${w}` : ""}.yml`), !L(C) || !G(C)) ? null : K.parse(J(C).toString());
1632
+ }, h = (g, m) => {
1633
+ try {
1634
+ const w = se(`*.${m}.yml`, { cwd: g, absolute: !0 })[0];
1635
+ return w ? K.parse(J(w).toString()) : null;
1636
+ } catch (w) {
1637
+ f.error("parse component error", w);
1638
+ }
1639
+ return null;
1640
+ }, S = (g, m) => {
1641
+ let w = P(g, `${m}.yml`);
1642
+ return (!L(w) || !G(w).isFile()) && (w = P(g, m, "index.yml"), !L(w) || !G(w)) ? null : K.parse(J(w).toString());
1643
+ }, p = R(
1644
+ d.pages.map(({ slug: g }) => {
1645
+ const m = R(
1646
+ d.supportedLocales.map(({ locale: O }) => {
1647
+ const u = c ? I(c, ce(g), O) : void 0;
1648
+ if (u)
1649
+ return { locale: O, page: u };
1650
+ const b = c ? I(c, g, O) : void 0;
1651
+ return b && { locale: O, page: b };
1652
+ })
1653
+ ), w = m[0]?.page;
1654
+ if (!w)
1655
+ return null;
1656
+ const C = w.sections.map(_t);
1657
+ return {
1658
+ id: w.id || xe(),
1659
+ createdAt: w.createdAt,
1660
+ updatedAt: w.updatedAt,
1661
+ publishedAt: w.publishedAt,
1662
+ isPublic: w.isPublic ?? !0,
1663
+ templateConfig: w.templateConfig,
1664
+ slug: g,
1665
+ sections: Object.fromEntries(C.map((O) => [O.id, O])),
1666
+ sectionIds: C.map((O) => O.id),
1667
+ locales: Object.fromEntries(m.map(({ locale: O, page: u }) => [O, u.meta])),
1668
+ dataSource: w.dataSource ? Object.fromEntries(
1669
+ // 获取 dataSource 中所有 section ID
1670
+ [...new Set(m.flatMap(({ page: O }) => Object.keys(O.dataSource ?? {})))].map((O) => [
1671
+ O,
1672
+ Object.fromEntries(
1673
+ m.map(({ locale: u, page: b }) => {
1674
+ const T = b.dataSource?.[O];
1675
+ return [u, T || {}];
1676
+ })
1677
+ )
1678
+ ])
1679
+ ) : Object.fromEntries(
1680
+ // 获取所有 section ID
1681
+ [...new Set(m.flatMap(({ page: O }) => O.sections.map((u) => u.id)))].map((O) => [
1682
+ O,
1683
+ Object.fromEntries(
1684
+ m.map(({ locale: u, page: b }) => {
1685
+ const T = b.dataSource?.[O];
1686
+ if (T)
1687
+ return [u, T];
1688
+ const B = b.sections.find((W) => W.id === O);
1689
+ return [u, B?.properties || {}];
1690
+ })
1691
+ )
1692
+ ])
1693
+ )
1694
+ };
1695
+ })
1696
+ ), i = R(
1697
+ d?.routes?.map(({ path: g }) => {
1698
+ const m = l ? S(l, ce(g)) : void 0;
1699
+ return {
1700
+ ...m,
1701
+ id: m?.id || xe(),
1702
+ createdAt: m?.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
1703
+ updatedAt: m?.updatedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
1704
+ publishedAt: (/* @__PURE__ */ new Date(0)).toISOString(),
1705
+ path: m?.path ?? `/${m?.id}`,
1706
+ params: m?.params,
1707
+ handler: m?.handler ?? "Pages Kit",
1708
+ isPublic: m?.isPublic ?? !0,
1709
+ enabledGenerate: m?.enabledGenerate ?? !1,
1710
+ displayTemplateId: m?.displayTemplateId ?? void 0,
1711
+ dataSource: m?.dataSource ?? {}
1712
+ };
1713
+ }) ?? []
1714
+ ), y = a ? R(d.components?.map(({ id: g }) => h(a, g)) ?? []) : [];
1715
+ if (e) {
1716
+ const g = (...m) => {
1717
+ f.info(`[${n ? x(t) : x(P(t, "../../../../"))}] importAssets:`, ...m);
1718
+ };
1719
+ try {
1720
+ g("wait image-bin api ready"), await zt({
1721
+ resources: [`${xt(Zt)}/api/sdk/uploads`],
1722
+ validateStatus: (C) => C >= 200 && C <= 500
1723
+ }), g("image-bin api is ready");
1724
+ const m = {}, w = {};
1725
+ g("start to upload assets"), await Promise.allSettled([
1726
+ Ve(y, m, {
1727
+ getFilePath: (C) => a && P(a, C),
1728
+ onFinish: (C) => {
1729
+ g(`upload ${C.length} component assets`);
1730
+ }
1731
+ }),
1732
+ Ve(p, w, {
1733
+ getFilePath: (C, O) => {
1734
+ const u = Ce(p, O.slice(0, 1));
1735
+ return c && P(c, j(u.slug), C);
1736
+ },
1737
+ onFinish: (C) => {
1738
+ g(`upload ${C.length} page assets`);
1739
+ }
1740
+ })
1741
+ ]), g("upload assets done"), be.clear(), global.gc && global.gc();
1742
+ } catch (m) {
1743
+ g("Error during asset import:", m);
1744
+ }
1745
+ }
1746
+ const A = {};
1747
+ if (o) {
1748
+ const g = r && P(j(r), "../../resources/components"), m = R(
1749
+ d.resources?.components?.map(({ id: w }) => h(g, w)) ?? []
1750
+ );
1751
+ m.length > 0 && (A.components = Object.fromEntries(
1752
+ m.map((w, C) => [w.id, { index: C, component: w }])
1753
+ ));
1754
+ }
1755
+ return {
1756
+ supportedLocales: d.supportedLocales,
1757
+ pageIds: p.map((g) => g.id),
1758
+ components: Object.fromEntries(y.map((g, m) => [g.id, { index: m, data: g }])),
1759
+ pages: Object.fromEntries(p.map((g) => [g.id, g])),
1760
+ config: d.config || {},
1761
+ resources: A,
1762
+ routeIds: i.map((g) => g.id),
1763
+ routes: Object.fromEntries(i.map((g) => [g.id, g])),
1764
+ dataSourceIds: [],
1765
+ dataSources: {}
1766
+ };
1767
+ } finally {
1768
+ n && s && Je(s, { force: !0, recursive: !0 });
1769
+ }
1770
+ }
1771
+ async function Ge(t, e, {
1772
+ routes: o,
1773
+ mergeMode: s = "byUpdateTime",
1774
+ deleteRoutes: n = !1,
1775
+ publishMode: r = void 0
1776
+ } = {}) {
1777
+ try {
1778
+ r && Po(r);
1779
+ } catch (S) {
1780
+ f.error("clear preload page cache error", { error: S });
1781
+ }
1782
+ const { pages: c, pageIds: a, routeIds: l, routes: d, supportedLocales: I } = t;
1783
+ if (r === "production") {
1784
+ let S = o ?? [], p = null;
1785
+ for (const i of l ?? []) {
1786
+ const y = d?.[i];
1787
+ if (y?.params && y?.params.length > 0 && y?.paramsOptions && y?.paramsOptions.length > 0) {
1788
+ const A = Ae({
1789
+ basePath: y.path,
1790
+ params: y.params,
1791
+ routeId: y.id,
1792
+ paramsOptions: y.paramsOptions,
1793
+ currentIndex: 0,
1794
+ currentParams: [],
1795
+ currentOptionIds: [],
1796
+ result: []
1797
+ }), g = Object.fromEntries(A.map((m) => [`${i}-${m.paramOptionIds.join("-")}`, m]));
1798
+ p = { ...p || {}, ...g }, o || (S = [...S, ...A.map((m) => `${i}-${m.paramOptionIds.join("-")}`)]);
1799
+ } else o || S.push(i);
1800
+ }
1801
+ f.info("routeIds to be published: ", S);
1802
+ for (const i of S) {
1803
+ let y = i;
1804
+ if (y.includes("-")) {
1805
+ const [m] = y.split("-");
1806
+ y = m;
1807
+ }
1808
+ const A = d?.[y];
1809
+ if (!A) {
1810
+ const m = e.pageIds.indexOf(y);
1811
+ m !== -1 && n && (e.pageIds.splice(m, 1), delete e.pages[y]);
1812
+ for (const w of e.pageIds)
1813
+ w.includes(`${y}-`) && (e.pageIds.splice(e.pageIds.indexOf(w), 1), delete e.pages[w]);
1814
+ f.info("delete main route page", y);
1815
+ continue;
1816
+ }
1817
+ if (i.includes("-") && !p?.[i]) {
1818
+ const m = e.pageIds.indexOf(i);
1819
+ m !== -1 && n && (e.pageIds.splice(m, 1), delete e.pages[i]), f.info("delete page", i);
1820
+ continue;
1821
+ }
1822
+ if (!A.displayTemplateId) {
1823
+ f.info("no display template", i);
1824
+ continue;
1825
+ }
1826
+ const g = c[A.displayTemplateId];
1827
+ if (!g) {
1828
+ f.info("no template page", i);
1829
+ continue;
1830
+ }
1831
+ if (e.pageIds.includes(i)) {
1832
+ if (f.info("has need update page", i), s === "replace")
1833
+ e.pages[i] = Se({
1834
+ page: g,
1835
+ route: A,
1836
+ state: t,
1837
+ routeId: i,
1838
+ routePathInfo: p?.[i]
1839
+ }), f.info("replace page", i);
1840
+ else if (s === "byUpdateTime") {
1841
+ const m = e.pages[A.id];
1842
+ (!m || A.updatedAt && A.updatedAt > m.updatedAt) && (e.pages[i] = Se({
1843
+ page: g,
1844
+ route: A,
1845
+ state: t,
1846
+ routeId: i,
1847
+ routePathInfo: p?.[i]
1848
+ }), f.info("replace page by update time", i));
1849
+ }
1850
+ } else
1851
+ e.pageIds.push(i), e.pages[i] = Se({
1852
+ page: g,
1853
+ route: A,
1854
+ state: t,
1855
+ routeId: i,
1856
+ routePathInfo: p?.[i]
1857
+ }), f.info("add page", i);
1858
+ }
1859
+ if (n && !o)
1860
+ for (const i of e.pageIds)
1861
+ S?.includes(i) || (delete e.pages[i], f.info("delete page", i)), e.pageIds = [...e.pageIds].filter((y) => S?.includes(y));
1862
+ } else {
1863
+ for (const S of a) {
1864
+ const p = c[S];
1865
+ if (p)
1866
+ if (e.pageIds.includes(p.id)) {
1867
+ if (s === "replace")
1868
+ e.pages[p.id] = p;
1869
+ else if (s === "byUpdateTime") {
1870
+ const i = e.pages[p.id];
1871
+ (!i || p.updatedAt && p.updatedAt > i.updatedAt) && (e.pages[p.id] = p);
1872
+ }
1873
+ } else
1874
+ e.pageIds.push(p.id), e.pages[p.id] = p;
1875
+ }
1876
+ for (const S of l) {
1877
+ const p = d[S];
1878
+ if (p)
1879
+ if (e.routeIds.includes(p.id)) {
1880
+ if (s === "replace")
1881
+ e.routes[p.id] = p;
1882
+ else if (s === "byUpdateTime") {
1883
+ const i = e.routes[p.id];
1884
+ (!i || p.updatedAt && p.updatedAt > i.updatedAt) && (e.routes[p.id] = p);
1885
+ }
1886
+ } else
1887
+ e.routeIds.push(p.id), e.routes[p.id] = p;
1888
+ }
1889
+ }
1890
+ if (e.supportedLocales.splice(0, e.supportedLocales.length), e.supportedLocales.push(...Ft(I)), n)
1891
+ for (const S of Object.keys(e.components))
1892
+ delete e.components[S];
1893
+ let h = JSON.parse(JSON.stringify(t.components));
1894
+ h = Object.fromEntries(
1895
+ await Promise.all(
1896
+ Object.entries(h).map(async ([S, p]) => {
1897
+ const i = await rt(p?.data);
1898
+ return [
1899
+ S,
1900
+ {
1901
+ ...p,
1902
+ data: i
1903
+ }
1904
+ ];
1905
+ })
1906
+ )
1907
+ ), Object.assign(e.components, h), Object.assign(e.config, JSON.parse(JSON.stringify(t.config))), Pe(t.resources.components) || (e.resources.components = JSON.parse(JSON.stringify(t.resources.components || {})));
1908
+ }
1909
+ const rt = ue(
1910
+ async (t) => {
1911
+ if (!Pe(t?.properties))
1912
+ return t;
1913
+ if (t?.renderer?.type === "react-component") {
1914
+ const { script: e, PROPERTIES_SCHEMA: o } = t?.renderer || {};
1915
+ if (o || e && e.includes("PROPERTIES_SCHEMA"))
1916
+ try {
1917
+ const s = await ko(
1918
+ e ?? "",
1919
+ "PROPERTIES_SCHEMA",
1920
+ t.id,
1921
+ o
1922
+ );
1923
+ s && s.length > 0 && t && (t.properties = {}, s.forEach((n, r) => {
1924
+ t?.properties && (t.properties[n.id] = {
1925
+ index: r,
1926
+ data: n
1927
+ });
1928
+ }));
1929
+ } catch (s) {
1930
+ f.error("getPropertiesFromCode error", { componentId: t.id, name: t.name }, { error: s });
1931
+ }
1932
+ }
1933
+ return t;
1934
+ },
1935
+ {
1936
+ subdir: "getPropertiesFromCode"
1937
+ }
1938
+ );
1939
+ let pe, X, de, fe;
1940
+ const at = () => Rt({
1941
+ types: [
1942
+ { did: tt, type: Ue },
1943
+ { did: Ro, type: Ue }
1944
+ ]
1945
+ }), Yo = () => {
1946
+ const t = at(), e = {};
1947
+ return t.forEach((o) => {
1948
+ const s = se("**/.blocklet/pages/pages.config.yml", { cwd: o.path, absolute: !0 }).at(0), n = s && P(j(s), "../../chunks");
1949
+ if (n && L(n)) {
1950
+ const r = Ct(n);
1951
+ for (const c of r)
1952
+ e[c] = P(n, c);
1953
+ }
1954
+ }), e;
1955
+ };
1956
+ function it() {
1957
+ return pe = (async () => {
1958
+ const t = at();
1959
+ X = (await Promise.all(
1960
+ t.map(async (o) => {
1961
+ const s = o.path ? await Wo(o.path, { importAssets: !1 }) : void 0;
1962
+ return s ? { blockletId: o.did, state: s, blockletTitle: o.title } : void 0;
1963
+ })
1964
+ )).filter((o) => !!o), de = X.reduce(
1965
+ (o, s) => Object.assign(
1966
+ o,
1967
+ Object.fromEntries(
1968
+ Object.values(s.state.pages).map((n) => n ? [n?.id, { page: n, blockletId: s.blockletId }] : [])
1969
+ )
1970
+ ),
1971
+ {}
1972
+ );
1973
+ const e = X.reduce(
1974
+ (o, s) => Object.assign(
1975
+ o,
1976
+ Object.fromEntries(
1977
+ Object.values(s.state.components).map((n) => [n.data.id, { blockletId: s.blockletId, component: n.data }])
1978
+ )
1979
+ ),
1980
+ {}
1981
+ );
1982
+ fe = Object.fromEntries(
1983
+ await Promise.all(
1984
+ Object.entries(e).map(async ([o, s]) => {
1985
+ const n = await rt(s.component);
1986
+ return [
1987
+ o,
1988
+ {
1989
+ ...s,
1990
+ component: n
1991
+ }
1992
+ ];
1993
+ })
1994
+ )
1995
+ );
1996
+ })(), pe;
1997
+ }
1998
+ function qo(t) {
1999
+ const e = ze(
2000
+ async () => {
2001
+ await it().catch((o) => {
2002
+ f.error("load resource states error", { error: o });
2003
+ }), await t?.({
2004
+ states: X,
2005
+ pages: de,
2006
+ components: fe
2007
+ });
2008
+ },
2009
+ 3e3,
2010
+ // 3s
2011
+ { leading: !1, trailing: !0 }
2012
+ );
2013
+ return e(), E.events.on(E.Events.componentAdded, e), E.events.on(E.Events.componentRemoved, e), E.events.on(E.Events.componentStarted, e), E.events.on(E.Events.componentStopped, e), E.events.on(E.Events.componentUpdated, e), E.events.on(Fe, e), () => {
2014
+ E.events.off(E.Events.componentAdded, e), E.events.off(E.Events.componentRemoved, e), E.events.off(E.Events.componentStarted, e), E.events.off(E.Events.componentStopped, e), E.events.off(E.Events.componentUpdated, e), E.events.off(Fe, e);
2015
+ };
2016
+ }
2017
+ const ct = Symbol.for("GLOBAL_RESOURCE_STATES_LISTENER_KEY"), pt = globalThis;
2018
+ pt[ct]?.();
2019
+ pt[ct] = qo(async ({ pages: t, components: e }) => {
2020
+ const o = await v.getProjectIds();
2021
+ f.info(`start update resource states projects(${o.length})`, o), await Promise.race([
2022
+ new Promise((s) => {
2023
+ setTimeout(() => {
2024
+ s({});
2025
+ }, 30 * 1e3);
2026
+ }),
2027
+ Promise.all(
2028
+ o.map(async (s) => {
2029
+ lt({
2030
+ projectId: s,
2031
+ pages: t,
2032
+ components: e
2033
+ });
2034
+ })
2035
+ )
2036
+ ]).catch((s) => {
2037
+ f.error("update resource states failed:", s);
2038
+ });
2039
+ });
2040
+ v.startPeriodicCheck();
2041
+ process.on("beforeExit", () => {
2042
+ v.stopPeriodicCheck();
2043
+ });
2044
+ process.on("SIGINT", () => {
2045
+ v.stopPeriodicCheck(), process.exit(0);
2046
+ });
2047
+ process.on("SIGTERM", () => {
2048
+ v.stopPeriodicCheck(), process.exit(0);
2049
+ });
2050
+ async function lt({
2051
+ projectId: t,
2052
+ pages: e,
2053
+ components: o
2054
+ }) {
2055
+ const s = v.sharedInstances[t];
2056
+ if (!s) {
2057
+ f.info(`projectId: ${t} not found in sharedInstances`);
2058
+ return;
2059
+ }
2060
+ if (s.syncedStore.resources.pages = e, (await N.findByPk(t))?.useAllResources)
2061
+ s.syncedStore.resources.components = o;
2062
+ else {
2063
+ const c = (await Oe.findAll({ where: { projectId: t } })).map((l) => l.componentId), a = Object.fromEntries(
2064
+ Object.entries(o || {}).filter(([l]) => c.includes(l))
2065
+ );
2066
+ s.syncedStore.resources.components = a;
2067
+ }
2068
+ f.info(`update [${t}] resource states:`, {
2069
+ pages: Object.keys(s.syncedStore.resources.pages || {}).length,
2070
+ components: Object.keys(s.syncedStore.resources.components || {}).length
2071
+ });
2072
+ }
2073
+ async function Qo({
2074
+ ensureLoaded: t = !0
2075
+ } = {}) {
2076
+ return t && (pe ??= it(), await pe), { states: X, pages: de, components: fe };
2077
+ }
2078
+ E.events.on(E.Events.envUpdate, () => {
2079
+ v.pageUrlMapCache.clear(), f.info("clear all page url map cache");
2080
+ });
2081
+ export {
2082
+ tt as C,
2083
+ N as P,
2084
+ Ue as R,
2085
+ v as S,
2086
+ Qo as a,
2087
+ Us as b,
2088
+ _s as g,
2089
+ Ns as i,
2090
+ f as l,
2091
+ Ho as t
2092
+ };