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

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