@blocklet/pages-kit-inner-components 0.7.15 → 0.7.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/chunks/site-state-DcRV8ldn.js +1 -0
- package/lib/cjs/resources.js +1 -1
- package/lib/cjs/site-state.js +1 -1
- package/lib/es/chunks/{site-state-BfM2FqNf.js → site-state-wFgYwXCr.js} +166 -158
- package/lib/es/resources.js +1 -1
- package/lib/es/site-state.js +1 -1
- package/package.json +16 -16
- package/lib/cjs/chunks/site-state-Cffe1l1P.js +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const u=require("./components-aaduHC9E.js"),G=require("@syncedstore/core"),it=require("yjs"),ct=require("@blocklet/pages-kit/utils/data-source"),ne=require("@blocklet/pages-kit/utils/route"),lt=require("lodash/cloneDeep"),h=require("sequelize");require("sqlite3");const ut=require("@blocklet/sdk/lib/config"),_=require("ufo"),Be=require("lodash");require("crypto");const Z=require("fs"),pt=require("p-limit"),p=require("path"),dt=require("worker_threads"),Ue=require("@blocklet/pages-kit/utils/common"),ft=require("@blocklet/pages-kit/utils/page-model"),gt=require("@blocklet/pages-kit/utils/property"),Ee=require("@blocklet/sdk/lib/component"),mt=require("@reactivedata/reactive"),D=require("fs/promises"),re=require("glob"),ht=require("lib0/decoding"),yt=require("lib0/encoding"),St=require("lodash/debounce"),wt=require("lodash/get"),It=require("lodash/isEmpty"),bt=require("lodash/set"),Pt=require("lodash/union"),Ge=require("lru-cache"),jt=require("stream/promises"),Et=require("tar"),At=require("wait-on"),W=require("y-protocols/awareness"),fe=require("y-protocols/sync"),Dt=require("yaml"),$e=require("./html-dP5_4zu1.js");require("@blocklet/pages-kit/types/state");const M=t=>t&&t.__esModule?t:{default:t};function pe(t){if(t&&t.__esModule)return t;const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(t){for(const a in t)if(a!=="default"){const s=Object.getOwnPropertyDescriptor(t,a);Object.defineProperty(e,a,s.get?s:{enumerable:!0,get:()=>t[a]})}}return e.default=t,Object.freeze(e)}const q=pe(it),Ae=M(lt),E=M(ut),V=M(Z),De=M(pt),Ne=M(p),ge=pe(ht),L=pe(yt),Te=M(St),Re=M(wt),Oe=M(It),Me=M(bt),Tt=M(Pt),Rt=M(At),H=pe(Dt),Ot=h.DataTypes.sqlite.DATE.parse;h.DataTypes.sqlite.DATE.parse=(t,e)=>typeof t=="number"?new Date(t):Ot(t,e);const F=new h.Sequelize({dialect:"sqlite",storage:u.databaseUrl,benchmark:process.env.ENABLE_SEQUELIZE_BENCHMARK==="true",retry:{match:[/SQLITE_BUSY/],name:"query",max:10},logging:process.env.ENABLE_SEQUELIZE_LOGGING==="true"?console.log:!1});F.query("PRAGMA journal_mode = WAL;");F.query("PRAGMA synchronous = normal;");F.query("PRAGMA journal_size_limit = 67108864;");F.query("PRAGMA cache_size = 10000;");process.on("SIGINT",async()=>{await F.close(),process.exit(0)});process.on("SIGTERM",async()=>{await F.close(),process.exit(0)});async function Ct(t,e){try{if(t.getDialect()!=="sqlite")return;const[a]=await t.query("SELECT 1");if(!a||a.length===0)return;await t.query("PRAGMA shrink_memory;")}catch(a){if(a.name==="SequelizeConnectionError"||a?.message&&/closed!/.test(a.message))return;console.error("Failed to cleanup SQLite memory",e,a)}}let Se=null;Se&&clearInterval(Se);Se=setInterval(async()=>{u.logger.info("Start cleanupSqliteMemory"),await Ct(F,u.databaseUrl),u.logger.info("End cleanupSqliteMemory")},60*1e3*10);const kt="z8iZiDFg3vkkrPwsiba1TLXy3H9XHzFERsP8o",we="page",Ie="trigger-reload-project-resource",Ce=kt,Lt="z2qa7BQdkEb3TwYyEYC1psK6uvmGnHSUHt5RM",vt="z8iZiDFg3vkkrPwsiba1TLXy3H9XHzFERsP8o";class ke extends h.Model{}ke.init({id:{type:h.DataTypes.UUID,allowNull:!1,primaryKey:!0,defaultValue:h.DataTypes.UUIDV4},projectId:{type:h.DataTypes.UUID,allowNull:!1},componentId:{type:h.DataTypes.STRING,allowNull:!1}},{sequelize:F,tableName:"ProjectComponents",timestamps:!1});const _t="SLUG_INVALID",Y=t=>({error:"slugInvalid",code:_t,field:"slug",message:t}),Ut={error:"slugRequired",code:"SLUG_REQUIRED",field:"slug",message:()=>"Project slug is required"},$t={error:"slugAlreadyExists",code:"SLUG_EXISTS",field:"slug",message:t=>`Project slug "${t}" already exists`},Nt=[/\.\./,/<[^>]*>/,/%[0-9a-f]{2}/i,/[<>'"%;{}()\\]/,/\x00/,/\n|\r|\t|\v|\f/,/[^a-zA-Z0-9-_@/\\:]/],Fe=t=>{if(!t)return"";if(t==="/")return"/";const e=_.withoutTrailingSlash(t);return _.withLeadingSlash(e)||"/"},Mt=t=>t.did===vt;class $ extends h.Model{static async getProjectByIdOrSlug(e,a){return e?$.findOne({where:{[h.Op.or]:[{id:e},{slug:e}],...a?.createdBy?{createdBy:a.createdBy}:{}}}):null}static async validateProjectSlug({slug:e,projectId:a}){if(e==null)return null;if(e==="")return Ut;const s=e==="/"?"/":_.withoutTrailingSlash(_.withLeadingSlash(e)),o=Fe(s);if(s!=="/"&&s.endsWith("/"))return Y(r=>`Project slug "${r}" cannot end with /`);if(/\/{2,}/.test(s))return Y(r=>`Project slug "${r}" cannot contain consecutive /`);if(/\s/.test(s))return Y(r=>`Project slug "${r}" cannot contain whitespace`);if(Nt.some(r=>r.test(s)))return Y(r=>`Project slug "${r}" contains invalid characters`);if(E.default.components?.filter(r=>r.mountPoint&&!Mt(r)).some(r=>Fe(r.mountPoint)===o))return Y(r=>`Project slug "${r}" conflicts with existing blocklet`);const l=await $.findOne({where:{slug:s}});return l&&l?.id!==a?$t:null}}$.init({id:{type:h.DataTypes.UUID,defaultValue:h.DataTypes.UUIDV4,primaryKey:!0},name:{type:h.DataTypes.STRING,allowNull:!1},description:h.DataTypes.TEXT,createdAt:h.DataTypes.DATE,updatedAt:h.DataTypes.DATE,createdBy:{type:h.DataTypes.STRING,allowNull:!1},updatedBy:{type:h.DataTypes.STRING,allowNull:!1},slug:h.DataTypes.STRING,icon:h.DataTypes.STRING,pinnedAt:h.DataTypes.DATE,useAllResources:h.DataTypes.BOOLEAN,npmSecret:h.DataTypes.STRING,relatedBlocklets:{type:h.DataTypes.JSON,allowNull:!1,defaultValue:{},get(){const t=this.getDataValue("relatedBlocklets");if(typeof t=="object")return t??{};try{return t?JSON.parse(t):{}}catch(e){return u.logger.error("Failed to parse relatedBlocklets",{error:e,rawValue:t}),{}}},set(t){try{this.setDataValue("relatedBlocklets",t?JSON.stringify(t):"{}")}catch(e){u.logger.error("Failed to set relatedBlocklets",{error:e,value:t}),this.setDataValue("relatedBlocklets","{}")}}},productionState:{type:h.DataTypes.JSON,allowNull:!1,defaultValue:{},get(){const t=this.getDataValue("productionState");if(typeof t=="object")return t??{};try{return t?JSON.parse(t):{}}catch(e){return u.logger.error("Failed to parse productionState",{error:e,rawValue:t}),{}}},set(t){try{this.setDataValue("productionState",t?JSON.stringify(t):"{}")}catch(e){u.logger.error("Failed to set productionState",{error:e,value:t}),this.setDataValue("productionState","{}")}}},meta:{type:h.DataTypes.JSON,allowNull:!0}},{sequelize:F,paranoid:!0,indexes:[{name:"projects_slug_unique",unique:!0,fields:["slug"]},{name:"projects_created_by",fields:["createdBy"]},{name:"projects_pinned_updated_meta_not_null",fields:[{name:"pinnedAt",order:"DESC"},{name:"updatedAt",order:"DESC"}],where:{meta:{[h.Op.ne]:null}}}]});$.hasMany(ke,{foreignKey:"projectId",as:"components"});async function x(t){try{return await V.default.promises.access(t,V.default.constants.F_OK),!0}catch{return!1}}function Ve(t,e){return new Promise((a,s)=>{const o=V.default.createReadStream(t),n=V.default.createWriteStream(e);o.on("error",s),n.on("error",s),n.on("finish",a),o.pipe(n)})}async function ze(t,e){await V.default.promises.mkdir(e,{recursive:!0});const a=await V.default.promises.readdir(t,{withFileTypes:!0});for(const s of a){const o=Ne.default.join(t,s.name),n=Ne.default.join(e,s.name);s.isDirectory()?await ze(o,n):await Ve(o,n)}}async function Ft(t,e){(await V.default.promises.stat(t)).isDirectory()?await ze(t,e):await Ve(t,e)}class ee extends h.Model{}ee.init({id:{type:h.DataTypes.UUID,primaryKey:!0,defaultValue:h.DataTypes.UUIDV4},projectId:{type:h.DataTypes.UUID,allowNull:!1,comment:"Project ID"},urlPath:{type:h.DataTypes.STRING(512),allowNull:!1,unique:!0,comment:"URL path, e.g. /project-slug/page-slug or /en/project-slug/page-slug"},projectSlug:{type:h.DataTypes.STRING,allowNull:!0,comment:"Project slug"},pageSlug:{type:h.DataTypes.STRING,allowNull:!1,comment:"Page slug"},pageId:{type:h.DataTypes.UUID,allowNull:!1,comment:"Page ID"},routeId:{type:h.DataTypes.UUID,allowNull:!0,comment:"Route ID (for draft mode)"},locale:{type:h.DataTypes.STRING(10),allowNull:!0,comment:"Locale code, e.g. en, zh"},defaultLocale:{type:h.DataTypes.STRING(10),allowNull:!0,comment:"Default locale"},shouldRedirect:{type:h.DataTypes.BOOLEAN,defaultValue:!1,comment:"Whether this URL should redirect"},mainPage:{type:h.DataTypes.BOOLEAN,defaultValue:!1,comment:"Whether this is the main page"},isPublic:{type:h.DataTypes.BOOLEAN,allowNull:!1,defaultValue:!0,comment:"Whether the page is public"},publishedAt:{type:h.DataTypes.BIGINT,allowNull:!0,comment:"Published timestamp"},locales:{type:h.DataTypes.JSON,allowNull:!0,comment:"Supported locales array"},createdAt:h.DataTypes.DATE,updatedAt:h.DataTypes.DATE},{sequelize:F,tableName:"PageUrlMappings",timestamps:!0,indexes:[{name:"idx_project_id",fields:["projectId"]},{name:"idx_url_path",unique:!0,fields:["urlPath"]},{name:"idx_page_id",fields:["pageId"]}]});function qt(t){const{projectId:e,projectSlug:a,state:s}=t,o=a||e,n=Be.union(E.default.env.languages?.map(c=>c.code)||[],s.supportedLocales?.map(c=>c.locale)||[]),l={},r=(c,S)=>{o&&(l[_.joinURL("/",o,c)]={...S,shouldRedirect:!0,mainPage:!0}),l[_.joinURL("/",e,c)]={...S,shouldRedirect:!0,mainPage:!0};for(const j of n){const T={...S,locale:j};l[_.joinURL("/",j,e,c)]=T,o&&(l[_.joinURL("/",j,o,c)]=T)}};for(const c of s.pageIds||[]){const S=s.pages?.[c];if(!S||!S.isPublic)continue;const j={projectId:e,projectSlug:o,pageSlug:S.slug,pageId:c,defaultLocale:n?.[0],locales:n,publishedAt:s.config?.publishedAt,isPublic:S.isPublic};r(S.slug,j)}return l}async function xt(t,e,a){const s=t.map(n=>n.urlPath),o=await ee.findAll({where:{urlPath:{[h.Op.in]:s},projectId:{[h.Op.ne]:e}},attributes:["urlPath","projectId","projectSlug","pageSlug"],transaction:a,raw:!0});if(o.length>0){u.logger.warn(`[URL Duplicate Warning] Found ${o.length} URL conflicts for project ${e}:`);for(const n of o){const l=t.find(r=>r.urlPath===n.urlPath);if(l){const r=n.projectSlug?_.joinURL(n.projectSlug,n.pageSlug):n.pageSlug;u.logger.warn(` - URL "${n.urlPath}" conflicts with project ${n.projectId} (${r}). Current project trying to use same URL for page: ${l.pageSlug}`)}}u.logger.warn("[URL Duplicate Warning] These duplicate URLs will be ignored during save. Consider using different project slugs or page slugs to avoid conflicts.")}}async function Bt(t){const{projectId:e,transaction:a}=t;try{await ee.destroy({where:{projectId:e},transaction:a});const s=qt(t),o=Object.entries(s).map(([n,l])=>({projectId:e,urlPath:n,projectSlug:l.projectSlug,pageSlug:l.pageSlug,pageId:l.pageId,routeId:l.routeId,locale:l.locale,defaultLocale:l.defaultLocale,shouldRedirect:l.shouldRedirect,mainPage:l.mainPage,isPublic:l.isPublic,publishedAt:typeof l.publishedAt=="number"?l.publishedAt:void 0,locales:l.locales}));if(o.length>0){await xt(o,e,a);const n=100,l=[];for(let r=0;r<o.length;r+=n){const c=o.slice(r,r+n);l.push(ee.bulkCreate(c,{transaction:a,ignoreDuplicates:!0}))}await Promise.all(l),u.logger.info(`Regenerated ${o.length} URL mappings for project ${e}`)}return o.length}catch(s){throw u.logger.error(`Failed to regenerate URL mappings for project ${e}:`,s),s}}function ie(t){t.observeDeep(e=>{e.some(a=>a.changes.keys.has("updatedAt")||a.changes.keys.has("publishedAt"))||t.set("updatedAt",new Date().toISOString())})}function He(){return Z.mkdtempSync(p.join(E.default.env.dataDir,"tmp-"))}function ce(t,e,a=[]){return Array.isArray(t)?t.flatMap((s,o)=>ce(s,e,[...a,o])):typeof t=="object"?t===null?[]:Object.entries(t).flatMap(([s,o])=>ce(o,e,[...a,s])):e(t)?[a]:[]}function U(t){return t.filter(e=>e!=null)}function Gt(t){return new Promise((e,a)=>{let s;process.env.NODE_ENV==="development"?s=p.join(__dirname,"yaml-worker.js"):s=p.join(__dirname,"api/dist/utils/yaml-worker.js");const o=new dt.Worker(s);o.postMessage({payload:t}),o.on("message",n=>{n.status==="success"?e(n.result):a(new Error(`YAML stringify failed in worker: ${n.message}`)),o.terminate()}),o.on("error",n=>{a(n)}),o.on("exit",n=>{n!==0&&a(new Error(`Worker stopped with exit code ${n}`))})})}function Vt(t){t.pages&&Object.keys(t.pages).forEach(a=>{const s=G.getYjsValue(t.pages[a]);s&&s instanceof q.Map&&ie(s)});const e=G.getYjsValue(t.pages);e&&e instanceof q.Map&&e.observe(a=>{a.changes.keys.forEach((s,o)=>{if(s.action==="add"){const n=G.getYjsValue(t.pages[o]);n&&n instanceof q.Map&&ie(n)}})})}function zt(t){t.routes&&Object.keys(t.routes).forEach(a=>{const s=G.getYjsValue(t.routes?.[a]);s&&s instanceof q.Map&&ie(s)});const e=G.getYjsValue(t.routes);e&&e instanceof q.Map&&e.observe(a=>{a.changes.keys.forEach((s,o)=>{if(s.action==="add"){const n=G.getYjsValue(t.routes?.[o]);n&&n instanceof q.Map&&ie(n)}})})}function Ht(t,e){for(const a of e||Object.keys(t.routes||{})){let s=a,o=[];if(a.includes("-")){const[n,...l]=a.split("-");s=n,o=l||[]}if(t.routes?.[s]!==void 0){t.routes[s].publishedAt=new Date().toISOString();const n=t.routes[s];if(!n||!n.params||n.params.length===0)continue;if(a.includes("-")&&o.length>0){const l=ne.getRouteMetaDataByOptionIds(o,n);l&&(l.publishedAt=new Date().toISOString())}if(!e){const l=ne.generateParamCombinations({basePath:n.path,params:n.params,routeId:n.id,paramsOptions:n.paramsOptions,currentIndex:0,currentParams:[],currentOptionIds:[],result:[]});for(const r of l)r.routeMetaData??={},r.routeMetaData.publishedAt=new Date().toISOString()}}}}function me({page:t,route:e,state:a,routeId:s,routePathInfo:o}){u.logger.info(`Executing datasource data assembly, routeId: ${s}, routePathInfo: ${JSON.stringify(o)}`);const n={...Ae.default(t),id:s,slug:o?.path??e.path,createdAt:e.createdAt,updatedAt:o?.routeMetaData?.updatedAt??e.updatedAt,publishedAt:o?.routeMetaData?.publishedAt??e.publishedAt,isPublic:(o?.routeMetaData?.isPublic??e.isPublic)&&e.isPublic};for(const l of a.supportedLocales){if(e.dataSource){let r=e.id;o&&(r=o.paramOptionIds.join("-"));const c=e.dataSource.pathDataMappings?.[r]?.dataCache?.[l.locale]??e.dataSource.pathDataMappings?.[r]?.dataCache?.[a.config.defaultLocale||"en"];if(!c)continue;ct.setPageDataSource(n,a,l.locale,c)}o&&o.routeMetaData&&(o.routeMetaData.publishedAt=new Date().toISOString())}return n}["true","1","yes","y"].includes(process.env.USE_FS_CACHE_HTML??"");const Kt=60*60*1e3,J=new Ge.LRUCache({max:300,ttl:Kt,ttlResolution:10*1e3,allowStale:!0});function Wt(t,e=[]){let a=0;const s=Array.from(J.keys()),o=t.map(n=>_.withoutTrailingSlash(n));for(const n of s)for(const l of o){if($e.matchCacheKey(n,{currentPath:l})){J.delete(n),a++,u.logger.info(`[Cache CLEAR] key: ${n}`);break}for(const r of e)if($e.matchCacheKey(n,{currentPath:`/${r}${l}`})){J.delete(n),a++,u.logger.info(`[Cache CLEAR] key: ${n}`);break}}return u.logger.info(`[Cache CLEAR] cleared ${a} entries for paths:`,o),a}function Yt(){const t=J.size;return J.clear(),u.logger.info(`[Cache CLEAR ALL] cleared ${t} entries`),t}const Jt=Be.debounce(Yt,300);E.default.events.on(E.default.Events.envUpdate,Jt);const{uploadToMediaKit:Xt}=require("@blocklet/uploader-server"),Le=/^\w+(\w|-|\.)+\w+\.(jpe?g|png|gif|svg|bmp|webp|mp4|m4v|webm)$/,X=/mediakit:\/\/([a-f0-9]{32}\.(jpe?g|png|gif|svg|bmp|webp|mp4|m4v|webm))/i,qe=/mediakit:\/\/([a-f0-9]{32}\.(jpe?g|png|gif|svg|bmp|webp|mp4|m4v|webm))/gi,Qt=1e4,Zt=3e4,se=0,he=1,ea=0,ta=1,be=E.default,z=p.join(process.env.BLOCKLET_DATA_DIR,"site-state"),aa=["production","draft"],sa=["production"];function le(t){return t?.replace(/\//g,"|")||""}function Ke(){const t=be.env.languages?.map(a=>({locale:a.code,name:a.name}))||[],e=t[0]?.locale||"en";return{pageIds:[],pages:{},routeIds:[],routes:{},dataSourceIds:[],dataSources:{},components:{},supportedLocales:t,config:{defaultLocale:e},resources:{}}}class C extends q.Doc{constructor(e){if(super(),this.options=e,Z.existsSync(this.draftYjsFilePath))try{q.applyUpdate(this,Z.readFileSync(this.draftYjsFilePath))}catch(a){u.logger.error("Failed to apply update from draft.yjs:",a)}this.syncedStore=mt.reactive(G.syncedStore({pages:{},pageIds:[],components:{},supportedLocales:[],config:{},resources:{},routeIds:[],routes:{},dataSourceIds:[],dataSources:{}},this)),this.initObserver(),this.on("update",this.updateHandler),this.awareness=new W.Awareness(this),this.awareness.on("update",this.awarenessChangeHandler),this.ensureDataStructure()}static RELEASE_DELAY=5*60*1e3;static PERIODIC_CHECK_INTERVAL=2*60*60*1e3;static sharedInstances={};static periodicCheckTimer;static async safeDeleteProjectStateDir(e){if(!e)throw new Error("Should provide project context");try{const a=p.join(z,e),s=p.join(z,`@del-${e}`);await D.rename(a,s)}catch(a){u.logger.error("Failed to safe delete project state dir:",a)}}static async getProjectIds(){return(await $.findAll({attributes:["id"],raw:!0}))?.map(e=>e.id)}static get projectIds(){return re.globSync("*/",{cwd:z,ignore:["@del-*","@tmp-*",".*","staging","production","@backup-*","undefined"]})}static get allShared(){return this.projectIds.map(e=>C.shared(e))}static shared(e){if(!e)throw new Error("Should provide project context");let a=C.sharedInstances[e];return a||(a=new C({path:p.join(z,e)}),C.sharedInstances[e]=a,a)}static async getProductionState(e){const a=await $.findByPk(e,{attributes:["productionState"]});if(Oe.default(a?.productionState)){const s=p.join(z,e,"production"),o=await ve(s,{includeResources:!0})??Ke();if(!o?.config?.defaultLocale){o.config??={};const n=be.env.languages?.map(l=>({locale:l.code,name:l.name}))||[];o.config.defaultLocale=n[0]?.locale}return o}return a?.productionState}destroy(){this.cancelRelease(),this.save({flush:!0}),this.conns.forEach((a,s)=>this.closeConn(s)),this.awareness.destroy();const e=p.basename(this.options.path);delete C.sharedInstances[e],super.destroy()}initObserver(){Vt(this.syncedStore),zt(this.syncedStore)}get draftYjsFilePath(){return p.join(this.options.path,"draft.yjs")}static async getStateByProjectId({projectId:e,mode:a,clone:s=!0}){if(a==="draft"){const o=C.shared(e);return s?JSON.parse(JSON.stringify(o.syncedStore)):o.syncedStore}return C.getProductionState(e)}async getState(e){if(e==="draft")return JSON.parse(JSON.stringify(this.syncedStore));const a=p.basename(this.options.path);return C.getProductionState(a)}async setState(e,a){if(e==="production"){const n=p.basename(this.options.path),l=Ae.default(a);await F.transaction(async r=>{await $.update({productionState:l},{where:{id:n},transaction:r});const c=await $.findByPk(n,{attributes:["slug"],transaction:r}),S=await Bt({projectId:n,projectSlug:c?.slug,state:a,transaction:r});u.logger.info(`[SiteState] saved ${S} URL mappings for project ${n}`)}),await this.clearPageCacheForRoutes(void 0,a)}const s=await Xe(a,{exportAssets:!1,includeResources:!0}),o=this.getPublishDir(e);await D.mkdir(p.dirname(o),{recursive:!0}),await D.rm(o,{force:!0,recursive:!0}),await D.rename(s,o)}getPublishDir(e){return p.join(this.options.path,e)}syncedStore;conns=new Map;awareness;releaseTimer;awarenessChangeHandler=({added:e,updated:a,removed:s},o)=>{const n=e.concat(a,s);if(o!==null){const c=this.conns.get(o);c&&(e.forEach(S=>{c.add(S)}),s.forEach(S=>{c.delete(S)}))}const l=L.createEncoder();L.writeVarUint(l,he),L.writeVarUint8Array(l,W.encodeAwarenessUpdate(this.awareness,n));const r=L.toUint8Array(l);this.conns.forEach((c,S)=>this.send(S,r))};updateHandler=e=>{const a=L.createEncoder();L.writeVarUint(a,se),fe.writeUpdate(a,e);const s=L.toUint8Array(a);this.conns.forEach((o,n)=>this.send(n,s))};ensureDataStructure=()=>{this.transact(()=>{const{supportedLocales:e,pages:a,pageIds:s,config:o,routes:n,routeIds:l}=this.syncedStore;{const r=new Set(Object.keys(a));let c=0;for(;c<s.length;){const S=s[c];r.has(S)?(r.delete(S),c++):s.splice(c,1)}}{const r=new Set(Object.keys(n));let c=0;for(;c<l.length;){const S=l[c];r.has(S)?(r.delete(S),c++):l.splice(c,1)}}e.splice(0,e.length),e.push(...be.env.languages.map(r=>({locale:r.code,name:r.name}))),o.defaultLocale=e[0]?.locale;{let r=0;const c=new Set;for(;r<e.length;){const{locale:S}=e[r];c.has(S)?e.splice(r,1):(r++,c.add(S))}}})};send=(e,a)=>{e.readyState!==ea&&e.readyState!==ta&&this.closeConn(e);try{e.send(a,s=>{s&&this.closeConn(e)})}catch{this.closeConn(e)}};closeConn=e=>{if(e.removeAllListeners(),this.conns.has(e)){const a=this.conns.get(e);this.conns.delete(e),a&&W.removeAwarenessStates(this.awareness,Array.from(a),null)}e.close(),this.checkAndScheduleRelease()};checkAndScheduleRelease(){this.conns.size===0&&this.scheduleRelease()}scheduleRelease(){this.cancelRelease();const e=p.basename(this.options.path);this.releaseTimer=setTimeout(()=>{u.logger.info(`[SiteState] releasing instance due to no active connections: ${e}`),this.conns.size===0&&(this.releaseTimer=void 0,this.destroy())},C.RELEASE_DELAY),u.logger.info(`[SiteState] scheduled release for project ${e} in ${C.RELEASE_DELAY/1e3}s`)}cancelRelease(){if(this.releaseTimer){clearTimeout(this.releaseTimer),this.releaseTimer=void 0;const e=p.basename(this.options.path);u.logger.info(`[SiteState] cancelled scheduled release for project ${e}`)}}autoSave=Te.default(async()=>{await D.mkdir(p.dirname(this.draftYjsFilePath),{recursive:!0}),await D.writeFile(this.draftYjsFilePath,q.encodeStateAsUpdate(this))},Qt);save=({flush:e=!1}={})=>{this.autoSave(),e&&this.autoSave.flush()};publish=async({mode:e,routes:a})=>{const s=p.basename(this.options.path);await nt(s);const o=await this.getState("draft"),n=await this.getState("production");await je(o,n,{routes:a,mergeMode:"replace",deleteRoutes:!0,publishMode:e}),n.config.publishedAt=new Date().getTime(),setImmediate(()=>{this.transact(()=>{Ht(this.syncedStore,a)})}),await this.setState(e,n)};mergeState=async(e,a)=>{const s=JSON.parse(JSON.stringify(a));e.config.fontFamily??={};const o=s.config?.fontFamily,n=e.config?.fontFamily;e.config.fontFamily.title=o?.title||n?.title,e.config.fontFamily.description=o?.description||n?.description,await new Promise((l,r)=>{this.transact(async()=>{try{const c=await je(e,a);l(c)}catch(c){r(c)}})})};clearPageCacheForRoutes=async(e,a)=>{const s=p.basename(this.options.path),n=(await $.findByPk(s))?.slug||s;let l=e;(!l||l.length===0)&&(l=a.pageIds??[]),u.logger.info(`[SiteState] clearing page cache for project ${s}, routes:`,l||[]);const r=a.supportedLocales.map(j=>j.locale),c=[],S=l.filter(j=>a.pageIds?.includes(j));for(const j of S){const b=a.pages[j].slug;n&&n!==s&&(n==="/"?c.push(b):c.push(`${n.startsWith("/")?"":"/"}${n}${b}`)),c.push(`/${s}${b}`)}if(c.length>0)try{const j=Wt(c,r);u.logger.info(`[SiteState] cleared ${j} page cache entries for project ${s}, routes:`,l)}catch{}};addConnection=e=>{if(this.conns.has(e))return;this.cancelRelease(),e.binaryType="arraybuffer",this.conns.set(e,new Set),e.on("message",o=>this.messageListener(e,new Uint8Array(o)));let a=!0;const s=setInterval(()=>{if(!a)this.conns.has(e)&&this.closeConn(e),clearInterval(s);else if(this.conns.has(e)){a=!1;try{e.ping()}catch{this.closeConn(e),clearInterval(s)}}},Zt);e.on("close",()=>{this.closeConn(e),clearInterval(s)}),e.on("pong",()=>{a=!0});{const o=L.createEncoder();L.writeVarUint(o,se),fe.writeSyncStep1(o,this),this.send(e,L.toUint8Array(o));const n=this.awareness.getStates();if(n.size>0){const l=L.createEncoder();L.writeVarUint(l,he),L.writeVarUint8Array(l,W.encodeAwarenessUpdate(this.awareness,Array.from(n.keys()))),this.send(e,L.toUint8Array(l))}}};messageListener=(e,a)=>{try{const s=L.createEncoder(),o=ge.createDecoder(a),n=ge.readVarUint(o);switch(u.logger.info(`[SiteState] messageListener, messageType: ${n}`),n){case se:L.writeVarUint(s,se),fe.readSyncMessage(o,s,this,null),u.logger.info(`[SiteState] messageListener, encoder length: ${L.length(s)}`),L.length(s)>1&&(this.ensureDataStructure(),this.send(e,L.toUint8Array(s)));break;case he:{W.applyAwarenessUpdate(this.awareness,ge.readVarUint8Array(o),e);break}default:u.logger.warn(`Unsupported messageType ${n}`)}}catch(s){u.logger.error(s)}this.save()};static async pageUrlMap(e,a){if(u.logger.info(`[SiteState] get pageUrlMap, mode: ${e}, projectId: ${a}`),e==="production"){const n=a?{projectId:a}:{},l=await ee.findAll({where:n,raw:!0}),r={};for(const c of l)r[c.urlPath]={projectId:c.projectId,projectSlug:c.projectSlug,pageSlug:c.pageSlug,pageId:c.pageId,routeId:c.routeId,locale:c.locale,defaultLocale:c.defaultLocale,shouldRedirect:c.shouldRedirect,mainPage:c.mainPage,isPublic:c.isPublic,publishedAt:c.publishedAt,locales:c.locales};return u.logger.info(`[SiteState] loaded ${l.length} URL mappings from database`),r}let s=[];a?s=[a]:s=await this.getProjectIds();let o={};if(s?.length){u.logger.info("[SiteState] find project infos from database, projectIds: ",s);const n=30,l=De.default(5);for(let r=0;r<s.length;r+=n){const c=s.slice(r,r+n);u.logger.info(`[SiteState] processing project batch ${r/n+1}, ids: `,c);const S=await $.findAll({where:{id:{[h.Op.in]:c}},attributes:{exclude:["relatedBlocklets"]}});await Promise.all(S?.map(j=>l(async()=>{const T=j.id,b=j.slug||T,m={},d=await C.getStateByProjectId({projectId:j.id,mode:e,clone:!1}),P=Tt.default(E.default.env.languages?.map(A=>A.code)||[],d.supportedLocales?.map(A=>A.locale)||[]),R=(A,I)=>{b&&(m[_.joinURL("/",b,A)]={...I,shouldRedirect:!0,mainPage:!0}),m[_.joinURL("/",T,A)]={...I,shouldRedirect:!0,mainPage:!0};for(const k of P){const y={...I,locale:k};m[_.joinURL("/",k,T,A)]=y,b&&(m[_.joinURL("/",k,b,A)]=y)}};if(e==="draft")for(const A of d.routeIds||[]){const I=d?.routes?.[A];if(!I)continue;if(I.params&&I.params.length>0){const w=ne.generateParamCombinations({basePath:I.path,params:I.params,routeId:I.id,paramsOptions:I.paramsOptions,currentIndex:0,currentParams:[],currentOptionIds:[],result:[]});for(const i of w){const f=i.path,g={projectId:T,projectSlug:b,pageSlug:f,pageId:I.displayTemplateId||"",routeId:A,defaultLocale:P?.[0],locales:P,publishedAt:d.config.publishedAt,isPublic:I.isPublic&&i?.routeMetaData?.isPublic};R(f,g)}}const k=I.path,y={projectId:T,projectSlug:b,pageSlug:k,pageId:I.displayTemplateId||"",routeId:A,defaultLocale:P?.[0],locales:P,publishedAt:d.config.publishedAt,isPublic:I.isPublic};R(k,y)}for(const A of d.pageIds||[]){const I=d.pages[A];if(!I)continue;const k=I.slug,y=j.slug||T,w={projectId:T,projectSlug:y,pageSlug:k,pageId:A,defaultLocale:P?.[0],locales:P,publishedAt:d.config.publishedAt,isPublic:I.isPublic,templateConfig:I.templateConfig};R(k,w)}o={...o,...m}})))}}return u.logger.info("[SiteState] success get pageUrlMap"),o}getDocumentSize(){return q.encodeStateAsUpdate(this).byteLength}static getInstancesSizeInfo(){const e=[];for(const[a,s]of Object.entries(C.sharedInstances)){const o=s.getDocumentSize();e.push({projectId:a,sizeInBytes:o,sizeInMB:`${(o/(1024*1024)).toFixed(2)} MB`,activeConnections:s.conns.size})}return e}static startPeriodicCheck(){this.periodicCheckTimer||(this.periodicCheckTimer=setInterval(()=>{this.performPeriodicCheck()},this.PERIODIC_CHECK_INTERVAL),u.logger.info(`[SiteState] periodic check started, interval: ${this.PERIODIC_CHECK_INTERVAL/(60*60*1e3)} hours`))}static stopPeriodicCheck(){this.periodicCheckTimer&&(clearInterval(this.periodicCheckTimer),this.periodicCheckTimer=void 0,u.logger.info("[SiteState] periodic check stopped"))}static performPeriodicCheck(){const e=Object.keys(C.sharedInstances).length,a=[],s=[];for(const[o,n]of Object.entries(C.sharedInstances))n.conns.size===0?a.push({projectId:o,instance:n}):s.push({projectId:o,connections:n.conns.size});if(u.logger.info(`[SiteState] periodic check summary: total instances: ${e}, with connections: ${s.length}, without connections: ${a.length}`),a.length>0){u.logger.info(`[SiteState] releasing ${a.length} instances without connections:`,a.map(n=>n.projectId));let o=0;for(const{projectId:n,instance:l}of a)try{u.logger.info(`[SiteState] releasing instance due to periodic check: ${n}`),l.destroy(),o++}catch(r){u.logger.error(`[SiteState] failed to release instance ${n} during periodic check:`,r)}u.logger.info(`[SiteState] periodic check completed: ${o}/${a.length} instances released successfully`)}else e>0?u.logger.debug("[SiteState] periodic check: all instances have active connections"):u.logger.debug("[SiteState] periodic check: no instances exist")}}async function oa(t,e,a){if(!t||!await x(t)||!(await D.lstat(t)).isFile())return null;let o=a[t];return o||(o=(async()=>{try{return(await Xt({filePath:t,fileName:e}))?.data?.filename}catch(n){return u.logger.error(`Failed to upload asset ${t}:`,n),null}})(),a[t]=o),o}const We=async(t,e)=>{const a=p.basename(t),s=await Ee.call({name:Ce,path:_.joinURL("/uploads",a),responseType:"stream",method:"GET"});if(s.status>=200&&s.status<400){const o=Z.createWriteStream(e);await jt.pipeline(s.data,o)}else throw new Error(`download asset failed ${s.status}`)},Ye=async(t,e)=>{await Promise.all(t.map(async a=>{try{await We(a,p.join(e,p.basename(a)))}catch(s){u.logger.error(`Failed to export assets: ${a}, ${s}`)}}))};function Je(t){return Le.test(t)?[t]:X.test(t)?(qe.lastIndex=0,Array.from(t.matchAll(qe)).map(a=>a[1]).filter(a=>!!a)):[]}async function oe(t,e,a){const{getFilename:s,exportAssets:o,useWorker:n}=a,l=p.join(e,s(t));await D.mkdir(p.dirname(l),{recursive:!0});const r=n?await Gt(t):H.stringify(t);if(await D.writeFile(l,r),o){const S=ce(t,j=>typeof j=="string"&&(Le.test(j)||X.test(j))).map(j=>{const T=Re.default(t,j);return Je(T)}).flat().filter(Boolean);await Ye(S,p.dirname(l))}}const Pe=new Ge.LRUCache({max:100,ttl:1*60*1e3});async function xe(t,e,a){const s=ce(t,r=>typeof r=="string"&&(Le.test(r)||X.test(r))),o=De.default(2),n=s.map(r=>o(async()=>{try{const c=Re.default(t,r),S=Je(c);for(const j of S){const T=p.basename(j),b=a.getFilePath(j,r),m=b?`${b}:${T}`:T,d=Pe.get(m);if(d){X.test(c)||Me.default(t,r,d);return}const P=await oa(b,T,e);P&&(X.test(c)||Me.default(t,r,P),Pe.set(m,P))}}catch(c){u.logger.error(`Failed to process upload for path ${r.join(".")}:`,c.message||c.reason)}})),l=await Promise.allSettled(n);a.onFinish?.(l)}async function Xe(t,{exportAssets:e,pageIds:a="all",componentIds:s="all",rawConfig:o,includeResources:n=!1,routeIds:l="all"}={}){const r=a==="all"?t.pageIds:a,c=gt.getComponentDependencies({state:t,pageIds:r,componentIds:s==="all"?Object.keys(t.components):s});Object.entries(t.components).forEach(([i,f])=>{f.data?.renderer?.type==="component-template"&&c.push(i)});const S=l==="all"?t.routeIds:l,j=i=>({id:i.id,name:i.name,isTemplateSection:i.isTemplateSection??!1,templateDescription:i.templateDescription,component:i.component,config:i.config,visibility:i.visibility,sections:i?.sectionIds?U(i?.sectionIds?.map(f=>{const g=i.sections?.[f];return g&&j(g)})):void 0}),T=(i,f)=>({id:i.id,createdAt:i.createdAt,updatedAt:i.updatedAt,publishedAt:i.publishedAt,isPublic:i.isPublic??!0,templateConfig:i.templateConfig,meta:i.locales?.[f]??{},sections:U(i.sectionIds.map(g=>{const O=i.sections[g];return O&&j(O)})),dataSource:Object.fromEntries(Object.entries(i.dataSource||{}).map(([g,O])=>[g,O?.[f]??{}]))}),b=i=>({id:i.id,createdAt:i.createdAt,updatedAt:i.updatedAt,publishedAt:i.publishedAt,path:i.path,handler:i.handler,isPublic:i.isPublic??!0,params:i.params??[],enabledGenerate:i.enabledGenerate??!1,displayTemplateId:i.displayTemplateId,dataSource:i.dataSource}),m=U(S.map(i=>{const f=t.routes[i];return f&&b(f)})),d=U(t.supportedLocales.map(i=>i.locale).flatMap(i=>r.map(f=>{const g=t.pages[f];return g&&{locale:i,slug:g.slug,page:T(g,i)}}))),P=He(),R=p.join(P,"pages");await D.mkdir(R,{recursive:!0});const A=p.join(P,"components");await D.mkdir(A,{recursive:!0});const I=p.join(P,"routes");await D.mkdir(I,{recursive:!0});for(const{locale:i,slug:f,page:g}of d)await oe(g,R,{getFilename:()=>`${le(f)||"index"}.${i}.yml`,exportAssets:e,useWorker:!0});for(const i of m)await oe(i,I,{getFilename:()=>`${le(i.path)||"index"}.yml`,exportAssets:e});for(const i of c){const f=t.components[i]?.data;f&&await oe(f,A,{getFilename:g=>`${g.name||"unnamed"}.${g.id}.yml`,exportAssets:e})}const k=p.join(P,".blocklet/pages/pages.config.yml");await D.mkdir(p.dirname(k),{recursive:!0});const y={pages:U(r.map(i=>{const f=t.pages[i];return f&&{id:i,slug:f.slug}})),routes:U(S.map(i=>{const f=t.routes[i];return f&&{id:i,path:f.path}})),components:U(c.map(i=>{const f=t.components[i]?.data;return f&&{id:i,name:f.name}})),...n?{resources:{components:U(Object.keys(t.resources?.components||{}).filter(i=>c.includes(i)).map(i=>({id:i,name:t.resources?.components?.[i]?.component?.name})))}}:{},supportedLocales:t.supportedLocales,config:t.config};await D.writeFile(k,H.stringify(y));const w=p.join(P,"config.source.json");if(o&&await D.writeFile(w,JSON.stringify(o)),n){const i=p.join(P,"resources"),f=p.join(i,"components");await D.mkdir(f,{recursive:!0});for(const N of Object.keys(t?.resources?.components??{}).filter(v=>c.includes(v))){const v=t.resources?.components?.[N]?.component;v&&await oe(v,f,{getFilename:B=>`${B.name||"unnamed"}.${B.id}.yml`,exportAssets:e})}const g=p.join(P,"chunks");await D.mkdir(g,{recursive:!0});const O=await na();for(const N of Object.keys(t?.resources?.components??{}).filter(v=>c.includes(v))){const v=t.resources?.components?.[N]?.component;if(v&&v.renderer?.type==="react-component"){const B=v.renderer?.chunks??[];if(B?.length>0)for(const K of B){const _e=p.join(g,K),de=O?.[K];try{de&&await x(de)&&!await x(_e)&&await D.copyFile(de,_e)}catch(rt){u.logger.error(`copy chunk ${K} error`,rt.message)}}}}}return P}async function ve(t,{importAssets:e,includeResources:a}={}){if(!await x(t))return null;let s,o=!1;try{(await D.lstat(t)).isDirectory()?s=t:/\.(tgz|gz|tar)$/.test(t)&&(o=!0,s=He(),await Et.x({file:t,C:s}));const r=(await re.glob("**/.blocklet/pages/pages.config.yml",{cwd:s,absolute:!0}))[0],c=r&&p.join(p.dirname(r),"../../pages"),S=r&&p.join(p.dirname(r),"../../components"),j=r&&p.join(p.dirname(r),"../../routes");if(!r)return null;const T=await D.readFile(r,"utf-8"),b=H.parse(T),m=async(y,w,i)=>{let f=p.join(y,`${w}${i?`.${i}`:""}.yml`);if(!await x(f)&&(f=p.join(y,w,`index${i?`.${i}`:""}.yml`),!await x(f))||!(await D.lstat(f)).isFile())return null;const O=await D.readFile(f,"utf-8");return H.parse(O)},d=async(y,w)=>{try{const f=(await re.glob(`*.${w}.yml`,{cwd:y,absolute:!0}))[0];if(!f)return null;const g=await D.readFile(f,"utf-8");return H.parse(g)}catch(i){u.logger.error("parse component error",i)}return null},P=async(y,w)=>{let i=p.join(y,`${w}.yml`);if(!await x(i)&&(i=p.join(y,w,"index.yml"),!await x(i))||!(await D.lstat(i)).isFile())return null;const g=await D.readFile(i,"utf-8");return H.parse(g)},R=U(await Promise.all(b.pages.map(async({slug:y})=>{const w=U(await Promise.all(b.supportedLocales.map(async({locale:g})=>{const O=c?await m(c,le(y),g):void 0;if(O)return{locale:g,page:O};const N=c?await m(c,y,g):void 0;return N&&{locale:g,page:N}}))),i=w[0]?.page;if(!i)return null;const f=i.sections.map(ft.unzipSection);return{id:i.id||Ue.nextId(),createdAt:i.createdAt,updatedAt:i.updatedAt,publishedAt:i.publishedAt,isPublic:i.isPublic??!0,templateConfig:i.templateConfig,slug:y,sections:Object.fromEntries(f.map(g=>[g.id,g])),sectionIds:f.map(g=>g.id),locales:Object.fromEntries(w.map(({locale:g,page:O})=>[g,O.meta])),dataSource:i.dataSource?Object.fromEntries([...new Set(w.flatMap(({page:g})=>Object.keys(g.dataSource??{})))].map(g=>[g,Object.fromEntries(w.map(({locale:O,page:N})=>{const v=N.dataSource?.[g];return[O,v||{}]}))])):Object.fromEntries([...new Set(w.flatMap(({page:g})=>g.sections.map(O=>O.id)))].map(g=>[g,Object.fromEntries(w.map(({locale:O,page:N})=>{const v=N.dataSource?.[g];if(v)return[O,v];const B=N.sections.find(K=>K.id===g);return[O,B?.properties||{}]}))]))}}))),A=U(await Promise.all((b?.routes||[]).map(async({path:y})=>{const w=j?await P(j,le(y)):void 0;return{...w,id:w?.id||Ue.nextId(),createdAt:w?.createdAt??new Date().toISOString(),updatedAt:w?.updatedAt??new Date().toISOString(),publishedAt:new Date(0).toISOString(),path:w?.path??`/${w?.id}`,params:w?.params,handler:w?.handler??"Pages Kit",isPublic:w?.isPublic??!0,enabledGenerate:w?.enabledGenerate??!1,displayTemplateId:w?.displayTemplateId??void 0,dataSource:w?.dataSource??{}}}))),I=S?U(await Promise.all((b.components||[]).map(async({id:y})=>d(S,y)))):[];if(e){const y=(...w)=>{u.logger.info(`[${o?p.basename(t):p.basename(p.join(t,"../../../../"))}] importAssets:`,...w)};try{y("wait image-bin api ready"),await Rt.default({resources:[`${Ee.getComponentWebEndpoint(u.IMAGE_BIN_NAME)}/api/sdk/uploads`],validateStatus:f=>f>=200&&f<=500}),y("image-bin api is ready");const w={},i={};y("start to upload assets"),await Promise.allSettled([xe(I,w,{getFilePath:f=>S&&p.join(S,f),onFinish:f=>{y(`upload ${f.length} component assets`)}}),xe(R,i,{getFilePath:(f,g)=>{const O=Re.default(R,g.slice(0,1));return c&&p.join(c,p.dirname(O.slug),f)},onFinish:f=>{y(`upload ${f.length} page assets`)}})]),y("upload assets done"),Pe.clear(),global.gc&&global.gc()}catch(w){y("Error during asset import:",w)}}const k={};if(a){const y=r&&p.join(p.dirname(r),"../../resources/components"),w=U(await Promise.all((b.resources?.components||[]).map(async({id:i})=>d(y,i))));w.length>0&&(k.components=Object.fromEntries(w.map((i,f)=>[i.id,{index:f,component:i}])))}return{supportedLocales:b.supportedLocales,pageIds:R.map(y=>y.id),components:Object.fromEntries(I.map((y,w)=>[y.id,{index:w,data:y}])),pages:Object.fromEntries(R.map(y=>[y.id,y])),config:b.config||{},resources:k,routeIds:A.map(y=>y.id),routes:Object.fromEntries(A.map(y=>[y.id,y])),dataSourceIds:[],dataSources:{}}}finally{o&&s&&await D.rm(s,{force:!0,recursive:!0})}}async function je(t,e,{routes:a,mergeMode:s="byUpdateTime",deleteRoutes:o=!1,publishMode:n=void 0}={}){try{n&&u.clearPreloadComponentsCacheByMode(n)}catch(b){u.logger.error("clear preload page cache error",{error:b})}const{pages:l,pageIds:r,routeIds:c,routes:S,supportedLocales:j}=t;if(n==="production"){let b=a??[],m=null;for(const d of c??[]){const P=S?.[d];if(P?.params&&P?.params.length>0&&P?.paramsOptions&&P?.paramsOptions.length>0){const R=ne.generateParamCombinations({basePath:P.path,params:P.params,routeId:P.id,paramsOptions:P.paramsOptions,currentIndex:0,currentParams:[],currentOptionIds:[],result:[]}),A=Object.fromEntries(R.map(I=>[`${d}-${I.paramOptionIds.join("-")}`,I]));m={...m||{},...A},a||(b=[...b,...R.map(I=>`${d}-${I.paramOptionIds.join("-")}`)])}else a||b.push(d)}u.logger.info("routeIds to be published: ",b);for(const d of b){let P=d;if(P.includes("-")){const[I]=P.split("-");P=I}const R=S?.[P];if(!R){const I=e.pageIds.indexOf(P);I!==-1&&o&&(e.pageIds.splice(I,1),delete e.pages[P]);for(const k of e.pageIds)k.includes(`${P}-`)&&(e.pageIds.splice(e.pageIds.indexOf(k),1),delete e.pages[k]);u.logger.info("delete main route page",P);continue}if(d.includes("-")&&!m?.[d]){const I=e.pageIds.indexOf(d);I!==-1&&o&&(e.pageIds.splice(I,1),delete e.pages[d]),u.logger.info("delete page",d);continue}if(!R.displayTemplateId){u.logger.info("no display template",d);continue}const A=l[R.displayTemplateId];if(!A){u.logger.info("no template page",d);continue}if(e.pageIds.includes(d)){if(u.logger.info("has need update page",d),s==="replace")e.pages[d]=me({page:A,route:R,state:t,routeId:d,routePathInfo:m?.[d]}),u.logger.info("replace page",d);else if(s==="byUpdateTime"){const I=e.pages[R.id];(!I||R.updatedAt&&R.updatedAt>I.updatedAt)&&(e.pages[d]=me({page:A,route:R,state:t,routeId:d,routePathInfo:m?.[d]}),u.logger.info("replace page by update time",d))}}else e.pageIds.push(d),e.pages[d]=me({page:A,route:R,state:t,routeId:d,routePathInfo:m?.[d]}),u.logger.info("add page",d)}if(o&&!a)for(const d of e.pageIds)b?.includes(d)||(delete e.pages[d],u.logger.info("delete page",d)),e.pageIds=[...e.pageIds].filter(P=>b?.includes(P))}else{for(const b of r){const m=l[b];if(m)if(e.pageIds.includes(m.id)){if(s==="replace")e.pages[m.id]=m;else if(s==="byUpdateTime"){const d=e.pages[m.id];(!d||m.updatedAt&&m.updatedAt>d.updatedAt)&&(e.pages[m.id]=m)}}else e.pageIds.push(m.id),e.pages[m.id]=m}for(const b of c){const m=S[b];if(m)if(e.routeIds.includes(m.id)){if(s==="replace")e.routes[m.id]=m;else if(s==="byUpdateTime"){const d=e.routes[m.id];(!d||m.updatedAt&&m.updatedAt>d.updatedAt)&&(e.routes[m.id]=m)}}else e.routeIds.push(m.id),e.routes[m.id]=m}}if(e.supportedLocales.splice(0,e.supportedLocales.length),e.supportedLocales.push(...Ae.default(j)),o)for(const b of Object.keys(e.components))delete e.components[b];let T=JSON.parse(JSON.stringify(t.components));T=Object.fromEntries(await Promise.all(Object.entries(T).map(async([b,m])=>{const d=await Qe(m?.data);return[b,{...m,data:d}]}))),Object.assign(e.components,T),Object.assign(e.config,JSON.parse(JSON.stringify(t.config))),Oe.default(t.resources.components)||(e.resources.components=JSON.parse(JSON.stringify(t.resources.components||{})))}const Qe=u.memoizeWithFs(async t=>{if(!Oe.default(t?.properties))return t;if(t?.renderer?.type==="react-component"){const{script:e,PROPERTIES_SCHEMA:a}=t?.renderer||{};if(a||e&&e.includes("PROPERTIES_SCHEMA"))try{const s=await u.getExportSchemaValueFromCode(e??"","PROPERTIES_SCHEMA",t.id,a);s&&s.length>0&&t&&(t.properties={},s.forEach((o,n)=>{t?.properties&&(t.properties[o.id]={index:n,data:o})}))}catch(s){u.logger.error("getPropertiesFromCode error",{componentId:t.id,name:t.name},{error:s})}}return t},{subdir:"getPropertiesFromCode"});let ue,Q,te,ae;const Ze=()=>Ee.getResources({types:[{did:Ce,type:we},{did:Lt,type:we}]}),na=async()=>{const t=Ze(),e={};for(const a of t){const o=(await re.glob("**/.blocklet/pages/pages.config.yml",{cwd:a.path,absolute:!0}))[0],n=o&&p.join(p.dirname(o),"../../chunks");if(n&&await x(n)){const l=await D.readdir(n);for(const r of l)e[r]=p.join(n,r)}}return e};function et(){return ue=(async()=>{const t=Ze();Q=(await Promise.all(t.map(async a=>{const s=a.path?await ve(a.path,{importAssets:!1}):void 0;return s?{blockletId:a.did,state:s,blockletTitle:a.title}:void 0}))).filter(a=>!!a),te=Q.reduce((a,s)=>Object.assign(a,Object.fromEntries(Object.values(s.state.pages).map(o=>o?[o?.id,{page:o,blockletId:s.blockletId}]:[]))),{});const e=Q.reduce((a,s)=>Object.assign(a,Object.fromEntries(Object.values(s.state.components).map(o=>[o.data.id,{blockletId:s.blockletId,component:o.data}]))),{});ae=Object.fromEntries(await Promise.all(Object.entries(e).map(async([a,s])=>{const o=await Qe(s.component);return[a,{...s,component:o}]}))),u.logger.info(`reloadResourceStates success: ${Object.keys(ae||{}).length} components, ${Object.keys(te||{}).length} pages`)})(),ue}function tt(t){const e=Te.default(async()=>{await et().catch(a=>{u.logger.error("load resource states error",{error:a})}),await t?.({states:Q,pages:te,components:ae})},3e3,{leading:!1,trailing:!0});return E.default.events.on(E.default.Events.componentAdded,e),E.default.events.on(E.default.Events.componentRemoved,e),E.default.events.on(E.default.Events.componentStarted,e),E.default.events.on(E.default.Events.componentStopped,e),E.default.events.on(E.default.Events.componentUpdated,e),E.default.events.on(Ie,e),e(),()=>{E.default.events.off(E.default.Events.componentAdded,e),E.default.events.off(E.default.Events.componentRemoved,e),E.default.events.off(E.default.Events.componentStarted,e),E.default.events.off(E.default.Events.componentStopped,e),E.default.events.off(E.default.Events.componentUpdated,e),E.default.events.off(Ie,e)}}const at=Symbol.for("GLOBAL_RESOURCE_STATES_LISTENER_KEY"),st=globalThis;st[at]?.();st[at]=tt(async({pages:t,components:e})=>{const a=await C.getProjectIds();u.logger.info(`start update resource states projects(${a.length})`,a);const s=De.default(10);await Promise.race([new Promise(o=>{setTimeout(()=>{o({})},30*1e3)}),Promise.all(a.map(o=>s(async()=>{ot({projectId:o,pages:t,components:e})})))]).catch(o=>{u.logger.error("update resource states failed:",o)})});C.startPeriodicCheck();process.on("beforeExit",()=>{C.stopPeriodicCheck()});process.on("SIGINT",()=>{C.stopPeriodicCheck(),process.exit(0)});process.on("SIGTERM",()=>{C.stopPeriodicCheck(),process.exit(0)});async function ot({projectId:t,pages:e,components:a}){const s=C.sharedInstances[t];if(!s){u.logger.info(`projectId: ${t} not found in sharedInstances`);return}const o=await $.findByPk(t,{attributes:{exclude:["productionState","relatedBlocklets"]}});let n;if(o?.useAllResources)n=a;else{const r=(await ke.findAll({where:{projectId:t}})).map(c=>c.componentId);n=Object.fromEntries(Object.entries(a||{}).filter(([c])=>r.includes(c)))}s.transact(()=>{s.syncedStore.resources.pages=e,u.logger.info(`[${t}] pages resources updated: ${Object.keys(e||{}).length} pages`),s.syncedStore.resources.components=n,u.logger.info(`[${t}] components resources updated: ${Object.keys(n||{}).length} components`)}),u.logger.info(`update [${t}] resource states summary:`,{pages:Object.keys(s.syncedStore.resources.pages||{}).length,components:Object.keys(s.syncedStore.resources.components||{}).length})}const ye=new Map;async function nt(t){if(!ye.has(t)){const e=Te.default(async a=>ot({projectId:a,pages:te,components:ae}),3e3);ye.set(t,e)}return ye.get(t)(t)}async function ra(){u.logger.info("trigger reload all project resource"),E.default.events.emit(Ie)}async function ia({ensureLoaded:t=!0}={}){return t&&(ue??=et(),await ue),{states:Q,pages:te,components:ae}}exports.COMPONENT_DID=Ce;exports.PUBLISH_MODES=sa;exports.Project=$;exports.RESOURCE_TYPE=we;exports.SITE_STATE_PATH=z;exports.STATE_MODES=aa;exports.SiteState=C;exports.copyRecursive=Ft;exports.downloadAsset=We;exports.downloadAssets=Ye;exports.fromPackage=ve;exports.getDefaultState=Ke;exports.getResourceStates=ia;exports.initPackResourceStates=tt;exports.mergeState=je;exports.toPackage=Xe;exports.triggerReloadAllProjectResource=ra;exports.updateResourceStatesByProjectId=nt;
|
package/lib/cjs/resources.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const f=require("./chunks/components-aaduHC9E.js"),c=require("./chunks/site-state-
|
|
1
|
+
"use strict";const f=require("./chunks/components-aaduHC9E.js"),c=require("./chunks/site-state-DcRV8ldn.js"),U=require("express"),w=require("fs/promises"),T=require("joi"),M=require("lodash/groupBy"),q=require("lodash/sortBy"),C=require("@blocklet/sdk/lib/middlewares/auth"),L=require("@blocklet/sdk/lib/component"),J=require("path"),h=e=>e&&e.__esModule?e:{default:e},l=h(T),k=h(M),F=h(q),X=async(e,t,o)=>{try{const{projectId:s}=e.params;if(!s)return o();const n=await c.Project.findByPk(s,{attributes:{exclude:["productionState","relatedBlocklets"]}});if(!n)return t?.status(404).json({error:"Project not found"});const r=e.user?.did,i=e.user?.role||"UNKNOWN_ROLE";if(!r)return t?.status(401).json({error:"Authentication required"});if(f.isMultiTenant()){const I=n.createdBy===r,g=f.getMultiTenantAllProjectAccessPassports()?.includes?.(i);if(!I&&!g)return t?.status(403).json({error:"No permission to access this project in multi-tenant mode"})}else if(!["owner","admin","pagesEditor"].includes(i))return t?.status(403).json({error:"No permission to access this project in single-tenant mode"});e.project=n,e.projectId=s,o()}catch(s){f.logger.error("Project middleware error:",s),t?.status(400).json({error:"Internal server error"})}},S=(e,t,o)=>f.isMultiTenant()?C.authMiddleware()(e,t,o):C.authMiddleware({roles:["owner","admin","pagesEditor"]})(e,t,o),G=(e,t)=>{const o=L.getResourceExportDir({projectId:e,releaseId:t});return J.join(o,c.COMPONENT_DID,c.RESOURCE_TYPE)},y=U.Router(),D="@page",b="@component",m=":",R="ALL",A="@project",v=({pageId:e,projectId:t})=>[D,t,e].join(m),K=e=>{const[t,o,s]=e.split(m);if(t===D)return{pageId:s,projectId:o}},x=({componentId:e,projectId:t})=>[b,t,e].join(m),W=e=>{const[t,o,s]=e.split(m);if(t===b)return{componentId:s,projectId:o}},Y=e=>[A,e].join(m),$=e=>{const[t,o]=e.split(m);if(t===A)return o},z=e=>{try{return JSON.parse(e)}catch{}return{}};async function B(e){const t=await c.SiteState.getStateByProjectId({projectId:e,mode:"production"}),o=await c.Project.findByPk(e),s=t.pageIds.map(r=>{const i=t.pages[r];if(i)return{id:v({pageId:r,projectId:e}),name:i.slug}}).filter(Boolean),n=F.default(Object.values(t.components),r=>r.index).map(({data:r})=>({id:x({componentId:r.id,projectId:e}),name:r.name||r.id}));return{id:Y(e),name:o?.name||"Unnamed Project",children:[{id:v({pageId:R,projectId:e}),name:"Pages",children:s},{id:x({componentId:R,projectId:e}),name:"Components",children:n}]}}y.get("/resources",S,async(e,t)=>{const{projectId:o}=z(e.query.resourcesParams);if(o){e.params={...e.params,projectId:o},await X(e,t,()=>{});const r=await B(o);t.json({resources:[r]});return}const s=await c.Project.findAll({where:{}}),n=await Promise.all(s.map(r=>B(r.id)));t.json({resources:n})});const H=l.default.object({projectId:l.default.string().required().min(1),releaseId:l.default.string().allow(""),resources:l.default.array().items(l.default.string()).required(),locale:l.default.string().allow("")});y.post("/resources",S,async(e,t)=>{const{resources:o,projectId:s,releaseId:n}=await H.validateAsync(e.body),r="production",i=[],I=[];for(const a of o){if($(a))continue;const{pageId:d,projectId:P}=K(a)||{};if(d)d===R||d&&P&&i.push({pageId:d,projectId:P});else{const{componentId:j,projectId:u}=W(a)||{};j===R||j&&u&&I.push({componentId:j,projectId:u})}}const g=k.default(i,"projectId"),O=k.default(I,"projectId"),N=new Set([...Object.keys(g),...Object.keys(O)]),E=G(s,n);await w.rm(E,{recursive:!0,force:!0}),await w.mkdir(E,{recursive:!0});for(const a of N){const d=await c.SiteState.getStateByProjectId({projectId:a,mode:r}),P=g[a],j=O[a],u=P?.map(p=>p.pageId),_=j?.map(p=>p.componentId);if(u?.length||_?.length){const p=await c.toPackage(d,{exportAssets:!0,pageIds:u,componentIds:_});await c.copyRecursive(p,E),await w.rm(p,{recursive:!0,force:!0})}f.logger.info(`Exported resources for project ${a}`,{pageIds:u,componentIds:_})}t.json({})});y.get("/all-resources",S,async(e,t)=>{const{states:o}=await c.getResourceStates(),s=o?.map(n=>{const r={blockletId:n.blockletId,blockletTitle:n.blockletTitle,components:{}};if(n.state.components&&(r.components=n.state.components),Object.keys(r.components).length!==0)return r}).filter(Boolean);t.json(s)});module.exports=y;
|
package/lib/cjs/site-state.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});require("./chunks/components-aaduHC9E.js");const e=require("./chunks/site-state-
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});require("./chunks/components-aaduHC9E.js");const e=require("./chunks/site-state-DcRV8ldn.js"),u=require("@blocklet/pages-kit/utils/common");require("@blocklet/pages-kit/utils/page-model");require("@blocklet/pages-kit/utils/property");require("@blocklet/pages-kit/utils/route");require("@blocklet/sdk/lib/component");require("@blocklet/sdk/lib/config");require("@reactivedata/reactive");require("@syncedstore/core");require("fs");require("fs/promises");require("glob");require("lib0/decoding");require("lib0/encoding");require("lodash/cloneDeep");require("lodash/debounce");require("lodash/get");require("lodash/isEmpty");require("lodash/set");require("lodash/union");require("lru-cache");require("p-limit");require("path");require("sequelize");require("stream/promises");require("tar");require("ufo");require("wait-on");require("y-protocols/awareness");require("y-protocols/sync");require("yaml");require("yjs");const t=require("@blocklet/pages-kit/types/state");exports.PUBLISH_MODES=e.PUBLISH_MODES;exports.SITE_STATE_PATH=e.SITE_STATE_PATH;exports.STATE_MODES=e.STATE_MODES;exports.default=e.SiteState;exports.downloadAsset=e.downloadAsset;exports.downloadAssets=e.downloadAssets;exports.fromPackage=e.fromPackage;exports.getDefaultState=e.getDefaultState;exports.getResourceStates=e.getResourceStates;exports.initPackResourceStates=e.initPackResourceStates;exports.mergeState=e.mergeState;exports.toPackage=e.toPackage;exports.triggerReloadAllProjectResource=e.triggerReloadAllProjectResource;exports.updateResourceStatesByProjectId=e.updateResourceStatesByProjectId;Object.defineProperty(exports,"nextId",{enumerable:!0,get:()=>u.nextId});Object.keys(t).forEach(r=>{r!=="default"&&!Object.prototype.hasOwnProperty.call(exports,r)&&Object.defineProperty(exports,r,{enumerable:!0,get:()=>t[r]})});
|
|
@@ -2,9 +2,9 @@ import { d as ze, l as p, m as it, b as ct, I as lt, c as pt } from "./component
|
|
|
2
2
|
import { getYjsValue as W, syncedStore as ut } from "@syncedstore/core";
|
|
3
3
|
import * as F from "yjs";
|
|
4
4
|
import { setPageDataSource as dt } from "@blocklet/pages-kit/utils/data-source";
|
|
5
|
-
import { getRouteMetaDataByOptionIds as ft, generateParamCombinations as
|
|
5
|
+
import { getRouteMetaDataByOptionIds as ft, generateParamCombinations as Pe } from "@blocklet/pages-kit/utils/route";
|
|
6
6
|
import Ae from "lodash/cloneDeep";
|
|
7
|
-
import { DataTypes as
|
|
7
|
+
import { DataTypes as b, Sequelize as mt, Model as Ee, Op as Z } from "sequelize";
|
|
8
8
|
import "sqlite3";
|
|
9
9
|
import E from "@blocklet/sdk/lib/config";
|
|
10
10
|
import { withoutTrailingSlash as je, withLeadingSlash as qe, joinURL as x } from "ufo";
|
|
@@ -13,21 +13,21 @@ import "crypto";
|
|
|
13
13
|
import z, { mkdtempSync as yt, existsSync as St, readFileSync as wt, createWriteStream as It } from "fs";
|
|
14
14
|
import Oe from "p-limit";
|
|
15
15
|
import Le, { join as A, basename as $, dirname as M } from "path";
|
|
16
|
-
import { Worker as
|
|
16
|
+
import { Worker as bt } from "worker_threads";
|
|
17
17
|
import { nextId as $e } from "@blocklet/pages-kit/utils/common";
|
|
18
|
-
import { unzipSection as
|
|
18
|
+
import { unzipSection as Pt } from "@blocklet/pages-kit/utils/page-model";
|
|
19
19
|
import { getComponentDependencies as At } from "@blocklet/pages-kit/utils/property";
|
|
20
20
|
import { getComponentWebEndpoint as Et, getResources as jt, call as Ot } from "@blocklet/sdk/lib/component";
|
|
21
21
|
import { reactive as Rt } from "@reactivedata/reactive";
|
|
22
|
-
import { rename as Ue, mkdir as B, rm as We, writeFile as
|
|
23
|
-
import { globSync as
|
|
22
|
+
import { rename as Ue, mkdir as B, rm as We, writeFile as ie, lstat as ne, readFile as ae, copyFile as Ct, readdir as Dt } from "fs/promises";
|
|
23
|
+
import { globSync as kt, glob as ye } from "glob";
|
|
24
24
|
import * as fe from "lib0/decoding";
|
|
25
|
-
import * as
|
|
25
|
+
import * as v from "lib0/encoding";
|
|
26
26
|
import Re from "lodash/debounce";
|
|
27
27
|
import Ce from "lodash/get";
|
|
28
28
|
import De from "lodash/isEmpty";
|
|
29
29
|
import Ne from "lodash/set";
|
|
30
|
-
import
|
|
30
|
+
import vt from "lodash/union";
|
|
31
31
|
import { LRUCache as Je } from "lru-cache";
|
|
32
32
|
import { pipeline as Tt } from "stream/promises";
|
|
33
33
|
import { x as Lt } from "tar";
|
|
@@ -37,8 +37,8 @@ import { writeUpdate as _t, writeSyncStep1 as Ft, readSyncMessage as xt } from "
|
|
|
37
37
|
import * as q from "yaml";
|
|
38
38
|
import { m as _e } from "./html-CNFwwbdj.js";
|
|
39
39
|
import "@blocklet/pages-kit/types/state";
|
|
40
|
-
const Bt =
|
|
41
|
-
|
|
40
|
+
const Bt = b.sqlite.DATE.parse;
|
|
41
|
+
b.sqlite.DATE.parse = (t, e) => typeof t == "number" ? new Date(t) : Bt(t, e);
|
|
42
42
|
const _ = new mt({
|
|
43
43
|
dialect: "sqlite",
|
|
44
44
|
storage: ze,
|
|
@@ -86,23 +86,23 @@ Se = setInterval(
|
|
|
86
86
|
// 10 minutes
|
|
87
87
|
);
|
|
88
88
|
const Vt = "z8iZiDFg3vkkrPwsiba1TLXy3H9XHzFERsP8o", Fe = "page", we = "trigger-reload-project-resource", Ke = Vt, zt = "z2qa7BQdkEb3TwYyEYC1psK6uvmGnHSUHt5RM", qt = "z8iZiDFg3vkkrPwsiba1TLXy3H9XHzFERsP8o";
|
|
89
|
-
class
|
|
89
|
+
class ke extends Ee {
|
|
90
90
|
// Foreign key to Component
|
|
91
91
|
}
|
|
92
|
-
|
|
92
|
+
ke.init(
|
|
93
93
|
{
|
|
94
94
|
id: {
|
|
95
|
-
type:
|
|
95
|
+
type: b.UUID,
|
|
96
96
|
allowNull: !1,
|
|
97
97
|
primaryKey: !0,
|
|
98
|
-
defaultValue:
|
|
98
|
+
defaultValue: b.UUIDV4
|
|
99
99
|
},
|
|
100
100
|
projectId: {
|
|
101
|
-
type:
|
|
101
|
+
type: b.UUID,
|
|
102
102
|
allowNull: !1
|
|
103
103
|
},
|
|
104
104
|
componentId: {
|
|
105
|
-
type:
|
|
105
|
+
type: b.STRING,
|
|
106
106
|
allowNull: !1
|
|
107
107
|
}
|
|
108
108
|
},
|
|
@@ -182,32 +182,32 @@ class U extends Ee {
|
|
|
182
182
|
U.init(
|
|
183
183
|
{
|
|
184
184
|
id: {
|
|
185
|
-
type:
|
|
186
|
-
defaultValue:
|
|
185
|
+
type: b.UUID,
|
|
186
|
+
defaultValue: b.UUIDV4,
|
|
187
187
|
primaryKey: !0
|
|
188
188
|
},
|
|
189
189
|
name: {
|
|
190
|
-
type:
|
|
190
|
+
type: b.STRING,
|
|
191
191
|
allowNull: !1
|
|
192
192
|
},
|
|
193
|
-
description:
|
|
194
|
-
createdAt:
|
|
195
|
-
updatedAt:
|
|
193
|
+
description: b.TEXT,
|
|
194
|
+
createdAt: b.DATE,
|
|
195
|
+
updatedAt: b.DATE,
|
|
196
196
|
createdBy: {
|
|
197
|
-
type:
|
|
197
|
+
type: b.STRING,
|
|
198
198
|
allowNull: !1
|
|
199
199
|
},
|
|
200
200
|
updatedBy: {
|
|
201
|
-
type:
|
|
201
|
+
type: b.STRING,
|
|
202
202
|
allowNull: !1
|
|
203
203
|
},
|
|
204
|
-
slug:
|
|
205
|
-
icon:
|
|
206
|
-
pinnedAt:
|
|
207
|
-
useAllResources:
|
|
208
|
-
npmSecret:
|
|
204
|
+
slug: b.STRING,
|
|
205
|
+
icon: b.STRING,
|
|
206
|
+
pinnedAt: b.DATE,
|
|
207
|
+
useAllResources: b.BOOLEAN,
|
|
208
|
+
npmSecret: b.STRING,
|
|
209
209
|
relatedBlocklets: {
|
|
210
|
-
type:
|
|
210
|
+
type: b.JSON,
|
|
211
211
|
allowNull: !1,
|
|
212
212
|
defaultValue: {},
|
|
213
213
|
get() {
|
|
@@ -229,7 +229,7 @@ U.init(
|
|
|
229
229
|
}
|
|
230
230
|
},
|
|
231
231
|
productionState: {
|
|
232
|
-
type:
|
|
232
|
+
type: b.JSON,
|
|
233
233
|
allowNull: !1,
|
|
234
234
|
defaultValue: {},
|
|
235
235
|
get() {
|
|
@@ -251,7 +251,7 @@ U.init(
|
|
|
251
251
|
}
|
|
252
252
|
},
|
|
253
253
|
meta: {
|
|
254
|
-
type:
|
|
254
|
+
type: b.JSON,
|
|
255
255
|
allowNull: !0
|
|
256
256
|
}
|
|
257
257
|
},
|
|
@@ -283,7 +283,7 @@ U.init(
|
|
|
283
283
|
]
|
|
284
284
|
}
|
|
285
285
|
);
|
|
286
|
-
U.hasMany(
|
|
286
|
+
U.hasMany(ke, {
|
|
287
287
|
foreignKey: "projectId",
|
|
288
288
|
as: "components"
|
|
289
289
|
});
|
|
@@ -316,79 +316,79 @@ class ee extends Ee {
|
|
|
316
316
|
ee.init(
|
|
317
317
|
{
|
|
318
318
|
id: {
|
|
319
|
-
type:
|
|
319
|
+
type: b.UUID,
|
|
320
320
|
primaryKey: !0,
|
|
321
|
-
defaultValue:
|
|
321
|
+
defaultValue: b.UUIDV4
|
|
322
322
|
},
|
|
323
323
|
projectId: {
|
|
324
|
-
type:
|
|
324
|
+
type: b.UUID,
|
|
325
325
|
allowNull: !1,
|
|
326
326
|
comment: "Project ID"
|
|
327
327
|
},
|
|
328
328
|
urlPath: {
|
|
329
|
-
type:
|
|
329
|
+
type: b.STRING(512),
|
|
330
330
|
allowNull: !1,
|
|
331
331
|
unique: !0,
|
|
332
332
|
comment: "URL path, e.g. /project-slug/page-slug or /en/project-slug/page-slug"
|
|
333
333
|
},
|
|
334
334
|
projectSlug: {
|
|
335
|
-
type:
|
|
335
|
+
type: b.STRING,
|
|
336
336
|
allowNull: !0,
|
|
337
337
|
comment: "Project slug"
|
|
338
338
|
},
|
|
339
339
|
pageSlug: {
|
|
340
|
-
type:
|
|
340
|
+
type: b.STRING,
|
|
341
341
|
allowNull: !1,
|
|
342
342
|
comment: "Page slug"
|
|
343
343
|
},
|
|
344
344
|
pageId: {
|
|
345
|
-
type:
|
|
345
|
+
type: b.UUID,
|
|
346
346
|
allowNull: !1,
|
|
347
347
|
comment: "Page ID"
|
|
348
348
|
},
|
|
349
349
|
routeId: {
|
|
350
|
-
type:
|
|
350
|
+
type: b.UUID,
|
|
351
351
|
allowNull: !0,
|
|
352
352
|
comment: "Route ID (for draft mode)"
|
|
353
353
|
},
|
|
354
354
|
locale: {
|
|
355
|
-
type:
|
|
355
|
+
type: b.STRING(10),
|
|
356
356
|
allowNull: !0,
|
|
357
357
|
comment: "Locale code, e.g. en, zh"
|
|
358
358
|
},
|
|
359
359
|
defaultLocale: {
|
|
360
|
-
type:
|
|
360
|
+
type: b.STRING(10),
|
|
361
361
|
allowNull: !0,
|
|
362
362
|
comment: "Default locale"
|
|
363
363
|
},
|
|
364
364
|
shouldRedirect: {
|
|
365
|
-
type:
|
|
365
|
+
type: b.BOOLEAN,
|
|
366
366
|
defaultValue: !1,
|
|
367
367
|
comment: "Whether this URL should redirect"
|
|
368
368
|
},
|
|
369
369
|
mainPage: {
|
|
370
|
-
type:
|
|
370
|
+
type: b.BOOLEAN,
|
|
371
371
|
defaultValue: !1,
|
|
372
372
|
comment: "Whether this is the main page"
|
|
373
373
|
},
|
|
374
374
|
isPublic: {
|
|
375
|
-
type:
|
|
375
|
+
type: b.BOOLEAN,
|
|
376
376
|
allowNull: !1,
|
|
377
377
|
defaultValue: !0,
|
|
378
378
|
comment: "Whether the page is public"
|
|
379
379
|
},
|
|
380
380
|
publishedAt: {
|
|
381
|
-
type:
|
|
381
|
+
type: b.BIGINT,
|
|
382
382
|
allowNull: !0,
|
|
383
383
|
comment: "Published timestamp"
|
|
384
384
|
},
|
|
385
385
|
locales: {
|
|
386
|
-
type:
|
|
386
|
+
type: b.JSON,
|
|
387
387
|
allowNull: !0,
|
|
388
388
|
comment: "Supported locales array"
|
|
389
389
|
},
|
|
390
|
-
createdAt:
|
|
391
|
-
updatedAt:
|
|
390
|
+
createdAt: b.DATE,
|
|
391
|
+
updatedAt: b.DATE
|
|
392
392
|
},
|
|
393
393
|
{
|
|
394
394
|
sequelize: _,
|
|
@@ -425,16 +425,16 @@ function Xt(t) {
|
|
|
425
425
|
shouldRedirect: !0,
|
|
426
426
|
mainPage: !0
|
|
427
427
|
};
|
|
428
|
-
for (const
|
|
429
|
-
const O = { ...h, locale:
|
|
430
|
-
l[x("/",
|
|
428
|
+
for (const P of r) {
|
|
429
|
+
const O = { ...h, locale: P };
|
|
430
|
+
l[x("/", P, e, c)] = O, o && (l[x("/", P, o, c)] = O);
|
|
431
431
|
}
|
|
432
432
|
};
|
|
433
433
|
for (const c of a.pageIds || []) {
|
|
434
434
|
const h = a.pages?.[c];
|
|
435
435
|
if (!h || !h.isPublic)
|
|
436
436
|
continue;
|
|
437
|
-
const
|
|
437
|
+
const P = {
|
|
438
438
|
projectId: e,
|
|
439
439
|
projectSlug: o,
|
|
440
440
|
pageSlug: h.slug,
|
|
@@ -444,7 +444,7 @@ function Xt(t) {
|
|
|
444
444
|
publishedAt: a.config?.publishedAt,
|
|
445
445
|
isPublic: h.isPublic
|
|
446
446
|
};
|
|
447
|
-
n(h.slug,
|
|
447
|
+
n(h.slug, P);
|
|
448
448
|
}
|
|
449
449
|
return l;
|
|
450
450
|
}
|
|
@@ -522,7 +522,7 @@ async function Zt(t) {
|
|
|
522
522
|
throw p.error(`Failed to regenerate URL mappings for project ${e}:`, a), a;
|
|
523
523
|
}
|
|
524
524
|
}
|
|
525
|
-
function
|
|
525
|
+
function ce(t) {
|
|
526
526
|
t.observeDeep((e) => {
|
|
527
527
|
e.some((s) => s.changes.keys.has("updatedAt") || s.changes.keys.has("publishedAt")) || t.set("updatedAt", (/* @__PURE__ */ new Date()).toISOString());
|
|
528
528
|
});
|
|
@@ -530,8 +530,8 @@ function ne(t) {
|
|
|
530
530
|
function Xe() {
|
|
531
531
|
return yt(A(E.env.dataDir, "tmp-"));
|
|
532
532
|
}
|
|
533
|
-
function
|
|
534
|
-
return Array.isArray(t) ? t.flatMap((a, o) =>
|
|
533
|
+
function le(t, e, s = []) {
|
|
534
|
+
return Array.isArray(t) ? t.flatMap((a, o) => le(a, e, [...s, o])) : typeof t == "object" ? t === null ? [] : Object.entries(t).flatMap(([a, o]) => le(o, e, [...s, a])) : e(t) ? [s] : [];
|
|
535
535
|
}
|
|
536
536
|
function L(t) {
|
|
537
537
|
return t.filter((e) => e != null);
|
|
@@ -540,7 +540,7 @@ function es(t) {
|
|
|
540
540
|
return new Promise((e, s) => {
|
|
541
541
|
let a;
|
|
542
542
|
process.env.NODE_ENV === "development" ? a = A(__dirname, "yaml-worker.js") : a = A(__dirname, "api/dist/utils/yaml-worker.js");
|
|
543
|
-
const o = new
|
|
543
|
+
const o = new bt(a);
|
|
544
544
|
o.postMessage({ payload: t }), o.on("message", (r) => {
|
|
545
545
|
r.status === "success" ? e(r.result) : s(new Error(`YAML stringify failed in worker: ${r.message}`)), o.terminate();
|
|
546
546
|
}), o.on("error", (r) => {
|
|
@@ -553,14 +553,14 @@ function es(t) {
|
|
|
553
553
|
function ts(t) {
|
|
554
554
|
t.pages && Object.keys(t.pages).forEach((s) => {
|
|
555
555
|
const a = W(t.pages[s]);
|
|
556
|
-
a && a instanceof F.Map &&
|
|
556
|
+
a && a instanceof F.Map && ce(a);
|
|
557
557
|
});
|
|
558
558
|
const e = W(t.pages);
|
|
559
559
|
e && e instanceof F.Map && e.observe((s) => {
|
|
560
560
|
s.changes.keys.forEach((a, o) => {
|
|
561
561
|
if (a.action === "add") {
|
|
562
562
|
const r = W(t.pages[o]);
|
|
563
|
-
r && r instanceof F.Map &&
|
|
563
|
+
r && r instanceof F.Map && ce(r);
|
|
564
564
|
}
|
|
565
565
|
});
|
|
566
566
|
});
|
|
@@ -568,14 +568,14 @@ function ts(t) {
|
|
|
568
568
|
function ss(t) {
|
|
569
569
|
t.routes && Object.keys(t.routes).forEach((s) => {
|
|
570
570
|
const a = W(t.routes?.[s]);
|
|
571
|
-
a && a instanceof F.Map &&
|
|
571
|
+
a && a instanceof F.Map && ce(a);
|
|
572
572
|
});
|
|
573
573
|
const e = W(t.routes);
|
|
574
574
|
e && e instanceof F.Map && e.observe((s) => {
|
|
575
575
|
s.changes.keys.forEach((a, o) => {
|
|
576
576
|
if (a.action === "add") {
|
|
577
577
|
const r = W(t.routes?.[o]);
|
|
578
|
-
r && r instanceof F.Map &&
|
|
578
|
+
r && r instanceof F.Map && ce(r);
|
|
579
579
|
}
|
|
580
580
|
});
|
|
581
581
|
});
|
|
@@ -597,7 +597,7 @@ function as(t, e) {
|
|
|
597
597
|
l && (l.publishedAt = (/* @__PURE__ */ new Date()).toISOString());
|
|
598
598
|
}
|
|
599
599
|
if (!e) {
|
|
600
|
-
const l =
|
|
600
|
+
const l = Pe({
|
|
601
601
|
basePath: r.path,
|
|
602
602
|
params: r.params,
|
|
603
603
|
routeId: r.id,
|
|
@@ -676,8 +676,8 @@ function ns() {
|
|
|
676
676
|
}
|
|
677
677
|
const is = ht(ns, 300);
|
|
678
678
|
E.events.on(E.Events.envUpdate, is);
|
|
679
|
-
const { uploadToMediaKit: cs } = require("@blocklet/uploader-server"),
|
|
680
|
-
function
|
|
679
|
+
const { uploadToMediaKit: cs } = require("@blocklet/uploader-server"), ve = /^\w+(\w|-|\.)+\w+\.(jpe?g|png|gif|svg|bmp|webp|mp4|m4v|webm)$/, X = /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, ls = 1e4, ps = 3e4, oe = 0, ge = 1, us = 0, ds = 1, Ie = E, H = A(process.env.BLOCKLET_DATA_DIR, "site-state"), aa = ["production", "draft"], oa = ["production"];
|
|
680
|
+
function pe(t) {
|
|
681
681
|
return t?.replace(/\//g, "|") || "";
|
|
682
682
|
}
|
|
683
683
|
function fs() {
|
|
@@ -697,7 +697,13 @@ function fs() {
|
|
|
697
697
|
}
|
|
698
698
|
class D extends F.Doc {
|
|
699
699
|
constructor(e) {
|
|
700
|
-
super(), this.options = e, St(this.draftYjsFilePath)
|
|
700
|
+
if (super(), this.options = e, St(this.draftYjsFilePath))
|
|
701
|
+
try {
|
|
702
|
+
F.applyUpdate(this, wt(this.draftYjsFilePath));
|
|
703
|
+
} catch (s) {
|
|
704
|
+
p.error("Failed to apply update from draft.yjs:", s);
|
|
705
|
+
}
|
|
706
|
+
this.syncedStore = Rt(
|
|
701
707
|
ut(
|
|
702
708
|
{
|
|
703
709
|
pages: {},
|
|
@@ -739,7 +745,7 @@ class D extends F.Doc {
|
|
|
739
745
|
}
|
|
740
746
|
/** @deprecated 不再使用这个 getter 了,仅作为兼容性处理,请使用 getProjectIds 代替 */
|
|
741
747
|
static get projectIds() {
|
|
742
|
-
return
|
|
748
|
+
return kt("*/", {
|
|
743
749
|
cwd: H,
|
|
744
750
|
ignore: ["@del-*", "@tmp-*", ".*", "staging", "production", "@backup-*", "undefined"]
|
|
745
751
|
// Ignore temp directories and hidden files
|
|
@@ -839,15 +845,15 @@ class D extends F.Doc {
|
|
|
839
845
|
c.delete(h);
|
|
840
846
|
}));
|
|
841
847
|
}
|
|
842
|
-
const l =
|
|
843
|
-
|
|
844
|
-
const n =
|
|
848
|
+
const l = v.createEncoder();
|
|
849
|
+
v.writeVarUint(l, ge), v.writeVarUint8Array(l, Me(this.awareness, r));
|
|
850
|
+
const n = v.toUint8Array(l);
|
|
845
851
|
this.conns.forEach((c, h) => this.send(h, n));
|
|
846
852
|
};
|
|
847
853
|
updateHandler = (e) => {
|
|
848
|
-
const s =
|
|
849
|
-
|
|
850
|
-
const a =
|
|
854
|
+
const s = v.createEncoder();
|
|
855
|
+
v.writeVarUint(s, oe), _t(s, e);
|
|
856
|
+
const a = v.toUint8Array(s);
|
|
851
857
|
this.conns.forEach((o, r) => this.send(r, a));
|
|
852
858
|
};
|
|
853
859
|
ensureDataStructure = () => {
|
|
@@ -918,7 +924,7 @@ class D extends F.Doc {
|
|
|
918
924
|
}
|
|
919
925
|
}
|
|
920
926
|
autoSave = Re(async () => {
|
|
921
|
-
await B(M(this.draftYjsFilePath), { recursive: !0 }), await
|
|
927
|
+
await B(M(this.draftYjsFilePath), { recursive: !0 }), await ie(this.draftYjsFilePath, F.encodeStateAsUpdate(this));
|
|
922
928
|
}, ls);
|
|
923
929
|
save = ({ flush: e = !1 } = {}) => {
|
|
924
930
|
this.autoSave(), e && this.autoSave.flush();
|
|
@@ -952,15 +958,15 @@ class D extends F.Doc {
|
|
|
952
958
|
const a = $(this.options.path), r = (await U.findByPk(a))?.slug || a;
|
|
953
959
|
let l = e;
|
|
954
960
|
(!l || l.length === 0) && (l = s.pageIds ?? []), p.info(`[SiteState] clearing page cache for project ${a}, routes:`, l || []);
|
|
955
|
-
const n = s.supportedLocales.map((
|
|
956
|
-
for (const
|
|
957
|
-
const w = s.pages[
|
|
961
|
+
const n = s.supportedLocales.map((P) => P.locale), c = [], h = l.filter((P) => s.pageIds?.includes(P));
|
|
962
|
+
for (const P of h) {
|
|
963
|
+
const w = s.pages[P].slug;
|
|
958
964
|
r && r !== a && (r === "/" ? c.push(w) : c.push(`${r.startsWith("/") ? "" : "/"}${r}${w}`)), c.push(`/${a}${w}`);
|
|
959
965
|
}
|
|
960
966
|
if (c.length > 0)
|
|
961
967
|
try {
|
|
962
|
-
const
|
|
963
|
-
p.info(`[SiteState] cleared ${
|
|
968
|
+
const P = rs(c, n);
|
|
969
|
+
p.info(`[SiteState] cleared ${P} page cache entries for project ${a}, routes:`, l);
|
|
964
970
|
} catch {
|
|
965
971
|
}
|
|
966
972
|
};
|
|
@@ -987,21 +993,21 @@ class D extends F.Doc {
|
|
|
987
993
|
s = !0;
|
|
988
994
|
});
|
|
989
995
|
{
|
|
990
|
-
const o =
|
|
991
|
-
|
|
996
|
+
const o = v.createEncoder();
|
|
997
|
+
v.writeVarUint(o, oe), Ft(o, this), this.send(e, v.toUint8Array(o));
|
|
992
998
|
const r = this.awareness.getStates();
|
|
993
999
|
if (r.size > 0) {
|
|
994
|
-
const l =
|
|
995
|
-
|
|
1000
|
+
const l = v.createEncoder();
|
|
1001
|
+
v.writeVarUint(l, ge), v.writeVarUint8Array(l, Me(this.awareness, Array.from(r.keys()))), this.send(e, v.toUint8Array(l));
|
|
996
1002
|
}
|
|
997
1003
|
}
|
|
998
1004
|
};
|
|
999
1005
|
messageListener = (e, s) => {
|
|
1000
1006
|
try {
|
|
1001
|
-
const a =
|
|
1007
|
+
const a = v.createEncoder(), o = fe.createDecoder(s), r = fe.readVarUint(o);
|
|
1002
1008
|
switch (p.info(`[SiteState] messageListener, messageType: ${r}`), r) {
|
|
1003
|
-
case
|
|
1004
|
-
|
|
1009
|
+
case oe:
|
|
1010
|
+
v.writeVarUint(a, oe), xt(o, a, this, null), p.info(`[SiteState] messageListener, encoder length: ${v.length(a)}`), v.length(a) > 1 && (this.ensureDataStructure(), this.send(e, v.toUint8Array(a)));
|
|
1005
1011
|
break;
|
|
1006
1012
|
case ge: {
|
|
1007
1013
|
Mt(this.awareness, fe.readVarUint8Array(o), e);
|
|
@@ -1060,8 +1066,8 @@ class D extends F.Doc {
|
|
|
1060
1066
|
});
|
|
1061
1067
|
await Promise.all(
|
|
1062
1068
|
h?.map(
|
|
1063
|
-
(
|
|
1064
|
-
const O =
|
|
1069
|
+
(P) => l(async () => {
|
|
1070
|
+
const O = P.id, w = P.slug || O, m = {}, u = await D.getStateByProjectId({ projectId: P.id, mode: e, clone: !1 }), I = vt(
|
|
1065
1071
|
E.env.languages?.map((j) => j.code) || [],
|
|
1066
1072
|
u.supportedLocales?.map((j) => j.locale) || []
|
|
1067
1073
|
), R = (j, S) => {
|
|
@@ -1074,9 +1080,9 @@ class D extends F.Doc {
|
|
|
1074
1080
|
shouldRedirect: !0,
|
|
1075
1081
|
mainPage: !0
|
|
1076
1082
|
};
|
|
1077
|
-
for (const
|
|
1078
|
-
const g = { ...S, locale:
|
|
1079
|
-
m[x("/",
|
|
1083
|
+
for (const k of I) {
|
|
1084
|
+
const g = { ...S, locale: k };
|
|
1085
|
+
m[x("/", k, O, j)] = g, w && (m[x("/", k, w, j)] = g);
|
|
1080
1086
|
}
|
|
1081
1087
|
};
|
|
1082
1088
|
if (e === "draft")
|
|
@@ -1084,7 +1090,7 @@ class D extends F.Doc {
|
|
|
1084
1090
|
const S = u?.routes?.[j];
|
|
1085
1091
|
if (!S) continue;
|
|
1086
1092
|
if (S.params && S.params.length > 0) {
|
|
1087
|
-
const y =
|
|
1093
|
+
const y = Pe({
|
|
1088
1094
|
basePath: S.path,
|
|
1089
1095
|
params: S.params,
|
|
1090
1096
|
routeId: S.id,
|
|
@@ -1110,10 +1116,10 @@ class D extends F.Doc {
|
|
|
1110
1116
|
R(d, f);
|
|
1111
1117
|
}
|
|
1112
1118
|
}
|
|
1113
|
-
const
|
|
1119
|
+
const k = S.path, g = {
|
|
1114
1120
|
projectId: O,
|
|
1115
1121
|
projectSlug: w,
|
|
1116
|
-
pageSlug:
|
|
1122
|
+
pageSlug: k,
|
|
1117
1123
|
pageId: S.displayTemplateId || "",
|
|
1118
1124
|
routeId: j,
|
|
1119
1125
|
// default locale
|
|
@@ -1122,15 +1128,15 @@ class D extends F.Doc {
|
|
|
1122
1128
|
publishedAt: u.config.publishedAt,
|
|
1123
1129
|
isPublic: S.isPublic
|
|
1124
1130
|
};
|
|
1125
|
-
R(
|
|
1131
|
+
R(k, g);
|
|
1126
1132
|
}
|
|
1127
1133
|
for (const j of u.pageIds || []) {
|
|
1128
1134
|
const S = u.pages[j];
|
|
1129
1135
|
if (!S) continue;
|
|
1130
|
-
const
|
|
1136
|
+
const k = S.slug, g = P.slug || O, y = {
|
|
1131
1137
|
projectId: O,
|
|
1132
1138
|
projectSlug: g,
|
|
1133
|
-
pageSlug:
|
|
1139
|
+
pageSlug: k,
|
|
1134
1140
|
pageId: j,
|
|
1135
1141
|
// default locale
|
|
1136
1142
|
defaultLocale: I?.[0],
|
|
@@ -1139,7 +1145,7 @@ class D extends F.Doc {
|
|
|
1139
1145
|
isPublic: S.isPublic,
|
|
1140
1146
|
templateConfig: S.templateConfig
|
|
1141
1147
|
};
|
|
1142
|
-
R(
|
|
1148
|
+
R(k, y);
|
|
1143
1149
|
}
|
|
1144
1150
|
o = { ...o, ...m };
|
|
1145
1151
|
})
|
|
@@ -1203,7 +1209,7 @@ class D extends F.Doc {
|
|
|
1203
1209
|
}
|
|
1204
1210
|
}
|
|
1205
1211
|
async function ms(t, e, s) {
|
|
1206
|
-
if (!t || !await G(t) || !(await
|
|
1212
|
+
if (!t || !await G(t) || !(await ne(t)).isFile())
|
|
1207
1213
|
return null;
|
|
1208
1214
|
let o = s[t];
|
|
1209
1215
|
return o || (o = (async () => {
|
|
@@ -1241,44 +1247,44 @@ const gs = async (t, e) => {
|
|
|
1241
1247
|
);
|
|
1242
1248
|
};
|
|
1243
1249
|
function Qe(t) {
|
|
1244
|
-
return
|
|
1250
|
+
return ve.test(t) ? [t] : X.test(t) ? (Be.lastIndex = 0, Array.from(t.matchAll(Be)).map((s) => s[1]).filter((s) => !!s)) : [];
|
|
1245
1251
|
}
|
|
1246
|
-
async function
|
|
1252
|
+
async function re(t, e, s) {
|
|
1247
1253
|
const { getFilename: a, exportAssets: o, useWorker: r } = s, l = A(e, a(t));
|
|
1248
1254
|
await B(M(l), { recursive: !0 });
|
|
1249
1255
|
const n = r ? await es(t) : q.stringify(t);
|
|
1250
|
-
if (await
|
|
1251
|
-
const h =
|
|
1256
|
+
if (await ie(l, n), o) {
|
|
1257
|
+
const h = le(
|
|
1252
1258
|
t,
|
|
1253
|
-
(
|
|
1254
|
-
).map((
|
|
1255
|
-
const O = Ce(t,
|
|
1259
|
+
(P) => typeof P == "string" && (ve.test(P) || X.test(P))
|
|
1260
|
+
).map((P) => {
|
|
1261
|
+
const O = Ce(t, P);
|
|
1256
1262
|
return Qe(O);
|
|
1257
1263
|
}).flat().filter(Boolean);
|
|
1258
1264
|
await hs(h, M(l));
|
|
1259
1265
|
}
|
|
1260
1266
|
}
|
|
1261
|
-
const
|
|
1267
|
+
const be = new Je({
|
|
1262
1268
|
max: 100,
|
|
1263
1269
|
ttl: 1 * 60 * 1e3
|
|
1264
1270
|
// 1 minute
|
|
1265
1271
|
});
|
|
1266
1272
|
async function Ge(t, e, s) {
|
|
1267
|
-
const a =
|
|
1273
|
+
const a = le(
|
|
1268
1274
|
t,
|
|
1269
|
-
(n) => typeof n == "string" && (
|
|
1275
|
+
(n) => typeof n == "string" && (ve.test(n) || X.test(n))
|
|
1270
1276
|
), o = Oe(2), r = a.map(
|
|
1271
1277
|
(n) => o(async () => {
|
|
1272
1278
|
try {
|
|
1273
1279
|
const c = Ce(t, n), h = Qe(c);
|
|
1274
|
-
for (const
|
|
1275
|
-
const O = $(
|
|
1280
|
+
for (const P of h) {
|
|
1281
|
+
const O = $(P), w = s.getFilePath(P, n), m = w ? `${w}:${O}` : O, u = be.get(m);
|
|
1276
1282
|
if (u) {
|
|
1277
1283
|
X.test(c) || Ne(t, n, u);
|
|
1278
1284
|
return;
|
|
1279
1285
|
}
|
|
1280
1286
|
const I = await ms(w, O, e);
|
|
1281
|
-
I && (X.test(c) || Ne(t, n, I),
|
|
1287
|
+
I && (X.test(c) || Ne(t, n, I), be.set(m, I));
|
|
1282
1288
|
}
|
|
1283
1289
|
} catch (c) {
|
|
1284
1290
|
p.error(`Failed to process upload for path ${n.join(".")}:`, c.message || c.reason);
|
|
@@ -1303,7 +1309,7 @@ async function ys(t, {
|
|
|
1303
1309
|
Object.entries(t.components).forEach(([i, d]) => {
|
|
1304
1310
|
d.data?.renderer?.type === "component-template" && c.push(i);
|
|
1305
1311
|
});
|
|
1306
|
-
const h = l === "all" ? t.routeIds : l,
|
|
1312
|
+
const h = l === "all" ? t.routeIds : l, P = (i) => ({
|
|
1307
1313
|
id: i.id,
|
|
1308
1314
|
name: i.name,
|
|
1309
1315
|
isTemplateSection: i.isTemplateSection ?? !1,
|
|
@@ -1316,7 +1322,7 @@ async function ys(t, {
|
|
|
1316
1322
|
sections: i?.sectionIds ? L(
|
|
1317
1323
|
i?.sectionIds?.map((d) => {
|
|
1318
1324
|
const f = i.sections?.[d];
|
|
1319
|
-
return f &&
|
|
1325
|
+
return f && P(f);
|
|
1320
1326
|
})
|
|
1321
1327
|
) : void 0
|
|
1322
1328
|
/** @deprecated 已经废弃,数据在 page.dataSource 中管理 */
|
|
@@ -1332,7 +1338,7 @@ async function ys(t, {
|
|
|
1332
1338
|
sections: L(
|
|
1333
1339
|
i.sectionIds.map((f) => {
|
|
1334
1340
|
const C = i.sections[f];
|
|
1335
|
-
return C &&
|
|
1341
|
+
return C && P(C);
|
|
1336
1342
|
})
|
|
1337
1343
|
),
|
|
1338
1344
|
// 将 dataSource.sectionId.locale 转换为 dataSource.sectionId
|
|
@@ -1374,26 +1380,26 @@ async function ys(t, {
|
|
|
1374
1380
|
const S = A(I, "routes");
|
|
1375
1381
|
await B(S, { recursive: !0 });
|
|
1376
1382
|
for (const { locale: i, slug: d, page: f } of u)
|
|
1377
|
-
await
|
|
1378
|
-
getFilename: () => `${
|
|
1383
|
+
await re(f, R, {
|
|
1384
|
+
getFilename: () => `${pe(d) || "index"}.${i}.yml`,
|
|
1379
1385
|
exportAssets: e,
|
|
1380
1386
|
useWorker: !0
|
|
1381
1387
|
});
|
|
1382
1388
|
for (const i of m)
|
|
1383
|
-
await
|
|
1389
|
+
await re(i, S, {
|
|
1384
1390
|
// getFilename: () => `${sanitizeSlug(route.path)}.yml`,
|
|
1385
|
-
getFilename: () => `${
|
|
1391
|
+
getFilename: () => `${pe(i.path) || "index"}.yml`,
|
|
1386
1392
|
exportAssets: e
|
|
1387
1393
|
});
|
|
1388
1394
|
for (const i of c) {
|
|
1389
1395
|
const d = t.components[i]?.data;
|
|
1390
|
-
d && await
|
|
1396
|
+
d && await re(d, j, {
|
|
1391
1397
|
getFilename: (f) => `${f.name || "unnamed"}.${f.id}.yml`,
|
|
1392
1398
|
exportAssets: e
|
|
1393
1399
|
});
|
|
1394
1400
|
}
|
|
1395
|
-
const
|
|
1396
|
-
await B(M(
|
|
1401
|
+
const k = A(I, ".blocklet/pages/pages.config.yml");
|
|
1402
|
+
await B(M(k), { recursive: !0 });
|
|
1397
1403
|
const g = {
|
|
1398
1404
|
pages: L(
|
|
1399
1405
|
n.map((i) => {
|
|
@@ -1429,16 +1435,16 @@ async function ys(t, {
|
|
|
1429
1435
|
supportedLocales: t.supportedLocales,
|
|
1430
1436
|
config: t.config
|
|
1431
1437
|
};
|
|
1432
|
-
await
|
|
1438
|
+
await ie(k, q.stringify(g));
|
|
1433
1439
|
const y = A(I, "config.source.json");
|
|
1434
|
-
if (o && await
|
|
1440
|
+
if (o && await ie(y, JSON.stringify(o)), r) {
|
|
1435
1441
|
const i = A(I, "resources"), d = A(i, "components");
|
|
1436
1442
|
await B(d, { recursive: !0 });
|
|
1437
1443
|
for (const N of Object.keys(t?.resources?.components ?? {}).filter(
|
|
1438
1444
|
(T) => c.includes(T)
|
|
1439
1445
|
)) {
|
|
1440
1446
|
const T = t.resources?.components?.[N]?.component;
|
|
1441
|
-
T && await
|
|
1447
|
+
T && await re(T, d, {
|
|
1442
1448
|
getFilename: (V) => `${V.name || "unnamed"}.${V.id}.yml`,
|
|
1443
1449
|
exportAssets: e
|
|
1444
1450
|
});
|
|
@@ -1471,21 +1477,21 @@ async function Ze(t, { importAssets: e, includeResources: s } = {}) {
|
|
|
1471
1477
|
return null;
|
|
1472
1478
|
let a, o = !1;
|
|
1473
1479
|
try {
|
|
1474
|
-
(await
|
|
1475
|
-
const n = (await ye("**/.blocklet/pages/pages.config.yml", { cwd: a, absolute: !0 }))[0], c = n && A(M(n), "../../pages"), h = n && A(M(n), "../../components"),
|
|
1480
|
+
(await ne(t)).isDirectory() ? a = t : /\.(tgz|gz|tar)$/.test(t) && (o = !0, a = Xe(), await Lt({ file: t, C: a }));
|
|
1481
|
+
const n = (await ye("**/.blocklet/pages/pages.config.yml", { cwd: a, absolute: !0 }))[0], c = n && A(M(n), "../../pages"), h = n && A(M(n), "../../components"), P = n && A(M(n), "../../routes");
|
|
1476
1482
|
if (!n)
|
|
1477
1483
|
return null;
|
|
1478
|
-
const O = await
|
|
1484
|
+
const O = await ae(n, "utf-8"), w = q.parse(O), m = async (g, y, i) => {
|
|
1479
1485
|
let d = A(g, `${y}${i ? `.${i}` : ""}.yml`);
|
|
1480
|
-
if (!await G(d) && (d = A(g, y, `index${i ? `.${i}` : ""}.yml`), !await G(d)) || !(await
|
|
1486
|
+
if (!await G(d) && (d = A(g, y, `index${i ? `.${i}` : ""}.yml`), !await G(d)) || !(await ne(d)).isFile())
|
|
1481
1487
|
return null;
|
|
1482
|
-
const C = await
|
|
1488
|
+
const C = await ae(d, "utf-8");
|
|
1483
1489
|
return q.parse(C);
|
|
1484
1490
|
}, u = async (g, y) => {
|
|
1485
1491
|
try {
|
|
1486
1492
|
const d = (await ye(`*.${y}.yml`, { cwd: g, absolute: !0 }))[0];
|
|
1487
1493
|
if (!d) return null;
|
|
1488
|
-
const f = await
|
|
1494
|
+
const f = await ae(d, "utf-8");
|
|
1489
1495
|
return q.parse(f);
|
|
1490
1496
|
} catch (i) {
|
|
1491
1497
|
p.error("parse component error", i);
|
|
@@ -1493,9 +1499,9 @@ async function Ze(t, { importAssets: e, includeResources: s } = {}) {
|
|
|
1493
1499
|
return null;
|
|
1494
1500
|
}, I = async (g, y) => {
|
|
1495
1501
|
let i = A(g, `${y}.yml`);
|
|
1496
|
-
if (!await G(i) && (i = A(g, y, "index.yml"), !await G(i)) || !(await
|
|
1502
|
+
if (!await G(i) && (i = A(g, y, "index.yml"), !await G(i)) || !(await ne(i)).isFile())
|
|
1497
1503
|
return null;
|
|
1498
|
-
const f = await
|
|
1504
|
+
const f = await ae(i, "utf-8");
|
|
1499
1505
|
return q.parse(f);
|
|
1500
1506
|
}, R = L(
|
|
1501
1507
|
await Promise.all(
|
|
@@ -1503,7 +1509,7 @@ async function Ze(t, { importAssets: e, includeResources: s } = {}) {
|
|
|
1503
1509
|
const y = L(
|
|
1504
1510
|
await Promise.all(
|
|
1505
1511
|
w.supportedLocales.map(async ({ locale: f }) => {
|
|
1506
|
-
const C = c ? await m(c,
|
|
1512
|
+
const C = c ? await m(c, pe(g), f) : void 0;
|
|
1507
1513
|
if (C)
|
|
1508
1514
|
return { locale: f, page: C };
|
|
1509
1515
|
const N = c ? await m(c, g, f) : void 0;
|
|
@@ -1513,7 +1519,7 @@ async function Ze(t, { importAssets: e, includeResources: s } = {}) {
|
|
|
1513
1519
|
), i = y[0]?.page;
|
|
1514
1520
|
if (!i)
|
|
1515
1521
|
return null;
|
|
1516
|
-
const d = i.sections.map(
|
|
1522
|
+
const d = i.sections.map(Pt);
|
|
1517
1523
|
return {
|
|
1518
1524
|
id: i.id || $e(),
|
|
1519
1525
|
createdAt: i.createdAt,
|
|
@@ -1557,7 +1563,7 @@ async function Ze(t, { importAssets: e, includeResources: s } = {}) {
|
|
|
1557
1563
|
), j = L(
|
|
1558
1564
|
await Promise.all(
|
|
1559
1565
|
(w?.routes || []).map(async ({ path: g }) => {
|
|
1560
|
-
const y =
|
|
1566
|
+
const y = P ? await I(P, pe(g)) : void 0;
|
|
1561
1567
|
return {
|
|
1562
1568
|
...y,
|
|
1563
1569
|
id: y?.id || $e(),
|
|
@@ -1603,19 +1609,19 @@ async function Ze(t, { importAssets: e, includeResources: s } = {}) {
|
|
|
1603
1609
|
g(`upload ${d.length} page assets`);
|
|
1604
1610
|
}
|
|
1605
1611
|
})
|
|
1606
|
-
]), g("upload assets done"),
|
|
1612
|
+
]), g("upload assets done"), be.clear(), global.gc && global.gc();
|
|
1607
1613
|
} catch (y) {
|
|
1608
1614
|
g("Error during asset import:", y);
|
|
1609
1615
|
}
|
|
1610
1616
|
}
|
|
1611
|
-
const
|
|
1617
|
+
const k = {};
|
|
1612
1618
|
if (s) {
|
|
1613
1619
|
const g = n && A(M(n), "../../resources/components"), y = L(
|
|
1614
1620
|
await Promise.all(
|
|
1615
1621
|
(w.resources?.components || []).map(async ({ id: i }) => u(g, i))
|
|
1616
1622
|
)
|
|
1617
1623
|
);
|
|
1618
|
-
y.length > 0 && (
|
|
1624
|
+
y.length > 0 && (k.components = Object.fromEntries(
|
|
1619
1625
|
y.map((i, d) => [i.id, { index: d, component: i }])
|
|
1620
1626
|
));
|
|
1621
1627
|
}
|
|
@@ -1625,7 +1631,7 @@ async function Ze(t, { importAssets: e, includeResources: s } = {}) {
|
|
|
1625
1631
|
components: Object.fromEntries(S.map((g, y) => [g.id, { index: y, data: g }])),
|
|
1626
1632
|
pages: Object.fromEntries(R.map((g) => [g.id, g])),
|
|
1627
1633
|
config: w.config || {},
|
|
1628
|
-
resources:
|
|
1634
|
+
resources: k,
|
|
1629
1635
|
routeIds: j.map((g) => g.id),
|
|
1630
1636
|
routes: Object.fromEntries(j.map((g) => [g.id, g])),
|
|
1631
1637
|
dataSourceIds: [],
|
|
@@ -1646,13 +1652,13 @@ async function Ve(t, e, {
|
|
|
1646
1652
|
} catch (w) {
|
|
1647
1653
|
p.error("clear preload page cache error", { error: w });
|
|
1648
1654
|
}
|
|
1649
|
-
const { pages: l, pageIds: n, routeIds: c, routes: h, supportedLocales:
|
|
1655
|
+
const { pages: l, pageIds: n, routeIds: c, routes: h, supportedLocales: P } = t;
|
|
1650
1656
|
if (r === "production") {
|
|
1651
1657
|
let w = s ?? [], m = null;
|
|
1652
1658
|
for (const u of c ?? []) {
|
|
1653
1659
|
const I = h?.[u];
|
|
1654
1660
|
if (I?.params && I?.params.length > 0 && I?.paramsOptions && I?.paramsOptions.length > 0) {
|
|
1655
|
-
const R =
|
|
1661
|
+
const R = Pe({
|
|
1656
1662
|
basePath: I.path,
|
|
1657
1663
|
params: I.params,
|
|
1658
1664
|
routeId: I.id,
|
|
@@ -1676,8 +1682,8 @@ async function Ve(t, e, {
|
|
|
1676
1682
|
if (!R) {
|
|
1677
1683
|
const S = e.pageIds.indexOf(I);
|
|
1678
1684
|
S !== -1 && o && (e.pageIds.splice(S, 1), delete e.pages[I]);
|
|
1679
|
-
for (const
|
|
1680
|
-
|
|
1685
|
+
for (const k of e.pageIds)
|
|
1686
|
+
k.includes(`${I}-`) && (e.pageIds.splice(e.pageIds.indexOf(k), 1), delete e.pages[k]);
|
|
1681
1687
|
p.info("delete main route page", I);
|
|
1682
1688
|
continue;
|
|
1683
1689
|
}
|
|
@@ -1754,7 +1760,7 @@ async function Ve(t, e, {
|
|
|
1754
1760
|
e.routeIds.push(m.id), e.routes[m.id] = m;
|
|
1755
1761
|
}
|
|
1756
1762
|
}
|
|
1757
|
-
if (e.supportedLocales.splice(0, e.supportedLocales.length), e.supportedLocales.push(...Ae(
|
|
1763
|
+
if (e.supportedLocales.splice(0, e.supportedLocales.length), e.supportedLocales.push(...Ae(P)), o)
|
|
1758
1764
|
for (const w of Object.keys(e.components))
|
|
1759
1765
|
delete e.components[w];
|
|
1760
1766
|
let O = JSON.parse(JSON.stringify(t.components));
|
|
@@ -1803,7 +1809,7 @@ const et = it(
|
|
|
1803
1809
|
subdir: "getPropertiesFromCode"
|
|
1804
1810
|
}
|
|
1805
1811
|
);
|
|
1806
|
-
let
|
|
1812
|
+
let ue, Q, te, se;
|
|
1807
1813
|
const tt = () => jt({
|
|
1808
1814
|
types: [
|
|
1809
1815
|
{ did: Ke, type: Fe },
|
|
@@ -1825,14 +1831,14 @@ const tt = () => jt({
|
|
|
1825
1831
|
return e;
|
|
1826
1832
|
};
|
|
1827
1833
|
function st() {
|
|
1828
|
-
return
|
|
1834
|
+
return ue = (async () => {
|
|
1829
1835
|
const t = tt();
|
|
1830
1836
|
Q = (await Promise.all(
|
|
1831
1837
|
t.map(async (s) => {
|
|
1832
1838
|
const a = s.path ? await Ze(s.path, { importAssets: !1 }) : void 0;
|
|
1833
1839
|
return a ? { blockletId: s.did, state: a, blockletTitle: s.title } : void 0;
|
|
1834
1840
|
})
|
|
1835
|
-
)).filter((s) => !!s),
|
|
1841
|
+
)).filter((s) => !!s), te = Q.reduce(
|
|
1836
1842
|
(s, a) => Object.assign(
|
|
1837
1843
|
s,
|
|
1838
1844
|
Object.fromEntries(
|
|
@@ -1850,7 +1856,7 @@ function st() {
|
|
|
1850
1856
|
),
|
|
1851
1857
|
{}
|
|
1852
1858
|
);
|
|
1853
|
-
|
|
1859
|
+
se = Object.fromEntries(
|
|
1854
1860
|
await Promise.all(
|
|
1855
1861
|
Object.entries(e).map(async ([s, a]) => {
|
|
1856
1862
|
const o = await et(a.component);
|
|
@@ -1863,8 +1869,10 @@ function st() {
|
|
|
1863
1869
|
];
|
|
1864
1870
|
})
|
|
1865
1871
|
)
|
|
1872
|
+
), p.info(
|
|
1873
|
+
`reloadResourceStates success: ${Object.keys(se || {}).length} components, ${Object.keys(te || {}).length} pages`
|
|
1866
1874
|
);
|
|
1867
|
-
})(),
|
|
1875
|
+
})(), ue;
|
|
1868
1876
|
}
|
|
1869
1877
|
function ws(t) {
|
|
1870
1878
|
const e = Re(
|
|
@@ -1873,15 +1881,15 @@ function ws(t) {
|
|
|
1873
1881
|
p.error("load resource states error", { error: s });
|
|
1874
1882
|
}), await t?.({
|
|
1875
1883
|
states: Q,
|
|
1876
|
-
pages:
|
|
1877
|
-
components:
|
|
1884
|
+
pages: te,
|
|
1885
|
+
components: se
|
|
1878
1886
|
});
|
|
1879
1887
|
},
|
|
1880
1888
|
3e3,
|
|
1881
1889
|
// 3s
|
|
1882
1890
|
{ leading: !1, trailing: !0 }
|
|
1883
1891
|
);
|
|
1884
|
-
return
|
|
1892
|
+
return 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(we, e), e(), () => {
|
|
1885
1893
|
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(we, e);
|
|
1886
1894
|
};
|
|
1887
1895
|
}
|
|
@@ -1939,7 +1947,7 @@ async function rt({
|
|
|
1939
1947
|
if (o?.useAllResources)
|
|
1940
1948
|
r = s;
|
|
1941
1949
|
else {
|
|
1942
|
-
const n = (await
|
|
1950
|
+
const n = (await ke.findAll({ where: { projectId: t } })).map((c) => c.componentId);
|
|
1943
1951
|
r = Object.fromEntries(Object.entries(s || {}).filter(([c]) => n.includes(c)));
|
|
1944
1952
|
}
|
|
1945
1953
|
a.transact(() => {
|
|
@@ -1954,8 +1962,8 @@ async function Is(t) {
|
|
|
1954
1962
|
if (!he.has(t)) {
|
|
1955
1963
|
const e = Re(async (s) => rt({
|
|
1956
1964
|
projectId: s,
|
|
1957
|
-
pages:
|
|
1958
|
-
components:
|
|
1965
|
+
pages: te,
|
|
1966
|
+
components: se
|
|
1959
1967
|
}), 3e3);
|
|
1960
1968
|
he.set(t, e);
|
|
1961
1969
|
}
|
|
@@ -1967,7 +1975,7 @@ async function ra() {
|
|
|
1967
1975
|
async function na({
|
|
1968
1976
|
ensureLoaded: t = !0
|
|
1969
1977
|
} = {}) {
|
|
1970
|
-
return t && (
|
|
1978
|
+
return t && (ue ??= st(), await ue), { states: Q, pages: te, components: se };
|
|
1971
1979
|
}
|
|
1972
1980
|
export {
|
|
1973
1981
|
Ke as C,
|
package/lib/es/resources.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { i as b, a as T, l as x } from "./chunks/components-D4ywfyMi.js";
|
|
2
|
-
import { P as E, C as L, R as M, S as A, t as F, c as J, g as X } from "./chunks/site-state-
|
|
2
|
+
import { P as E, C as L, R as M, S as A, t as F, c as J, g as X } from "./chunks/site-state-wFgYwXCr.js";
|
|
3
3
|
import { Router as G } from "express";
|
|
4
4
|
import { rm as C, mkdir as K } from "fs/promises";
|
|
5
5
|
import u from "joi";
|
package/lib/es/site-state.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "./chunks/components-D4ywfyMi.js";
|
|
2
|
-
import { d as b, a as h, b as y, S as L, f as U, h as q, i as v, e as z, g as C, j as F, m as G, t as J, k as K, u as N } from "./chunks/site-state-
|
|
2
|
+
import { d as b, a as h, b as y, S as L, f as U, h as q, i as v, e as z, g as C, j as F, m as G, t as J, k as K, u as N } from "./chunks/site-state-wFgYwXCr.js";
|
|
3
3
|
import { nextId as V } from "@blocklet/pages-kit/utils/common";
|
|
4
4
|
import "@blocklet/pages-kit/utils/page-model";
|
|
5
5
|
import "@blocklet/pages-kit/utils/property";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blocklet/pages-kit-inner-components",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.17",
|
|
4
4
|
"description": "Pages Kit inner components library",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -69,23 +69,23 @@
|
|
|
69
69
|
"url": "git+https://github.com/blocklet/pages-kit.git"
|
|
70
70
|
},
|
|
71
71
|
"dependencies": {
|
|
72
|
-
"@arcblock/did-connect-react": "^3.2.
|
|
72
|
+
"@arcblock/did-connect-react": "^3.2.3",
|
|
73
73
|
"@arcblock/did-connect-storage-nedb": "^1.8.0",
|
|
74
|
-
"@arcblock/react-hooks": "^3.2.
|
|
75
|
-
"@arcblock/ux": "^3.2.
|
|
74
|
+
"@arcblock/react-hooks": "^3.2.3",
|
|
75
|
+
"@arcblock/ux": "^3.2.3",
|
|
76
76
|
"@blocklet/aigne-hub": "^0.4.61",
|
|
77
77
|
"@blocklet/aigne-sdk": "^0.5.26",
|
|
78
78
|
"@blocklet/code-editor": "^0.5.26",
|
|
79
79
|
"@blocklet/embed": "^0.2.5",
|
|
80
|
-
"@blocklet/js-sdk": "^1.17.
|
|
81
|
-
"@blocklet/logger": "^1.17.
|
|
80
|
+
"@blocklet/js-sdk": "^1.17.2-beta-20251113-121338-9c917e68",
|
|
81
|
+
"@blocklet/logger": "^1.17.2-beta-20251113-121338-9c917e68",
|
|
82
82
|
"@blocklet/quickjs": "^0.5.26",
|
|
83
|
-
"@blocklet/sdk": "^1.17.
|
|
83
|
+
"@blocklet/sdk": "^1.17.2-beta-20251113-121338-9c917e68",
|
|
84
84
|
"@blocklet/studio-ui": "^0.5.26",
|
|
85
|
-
"@blocklet/tracker": "^1.17.
|
|
86
|
-
"@blocklet/ui-react": "^3.2.
|
|
87
|
-
"@blocklet/uploader": "^0.3.
|
|
88
|
-
"@blocklet/uploader-server": "^0.3.
|
|
85
|
+
"@blocklet/tracker": "^1.17.2-beta-20251113-121338-9c917e68",
|
|
86
|
+
"@blocklet/ui-react": "^3.2.3",
|
|
87
|
+
"@blocklet/uploader": "^0.3.10",
|
|
88
|
+
"@blocklet/uploader-server": "^0.3.10",
|
|
89
89
|
"@dnd-kit/core": "^6.3.1",
|
|
90
90
|
"@dnd-kit/modifiers": "^9.0.0",
|
|
91
91
|
"@dnd-kit/sortable": "^10.0.0",
|
|
@@ -107,9 +107,9 @@
|
|
|
107
107
|
"@mui/styles": "^5.16.14",
|
|
108
108
|
"@mui/utils": "^7.1.1",
|
|
109
109
|
"@mui/x-date-pickers": "^8.6.0",
|
|
110
|
-
"@ocap/client": "^1.27.
|
|
111
|
-
"@ocap/mcrypto": "^1.27.
|
|
112
|
-
"@ocap/wallet": "^1.27.
|
|
110
|
+
"@ocap/client": "^1.27.5",
|
|
111
|
+
"@ocap/mcrypto": "^1.27.5",
|
|
112
|
+
"@ocap/wallet": "^1.27.5",
|
|
113
113
|
"@reactivedata/reactive": "^0.2.2",
|
|
114
114
|
"@syncedstore/core": "^0.6.0",
|
|
115
115
|
"@syncedstore/react": "^0.6.0",
|
|
@@ -201,8 +201,8 @@
|
|
|
201
201
|
"yaml": "^2.5.0",
|
|
202
202
|
"yjs": "^13.6.18",
|
|
203
203
|
"zustand": "^4.5.5",
|
|
204
|
-
"@blocklet/pages-kit": "^0.7.
|
|
205
|
-
"@blocklet/pages-kit-block-studio": "^0.7.
|
|
204
|
+
"@blocklet/pages-kit": "^0.7.17",
|
|
205
|
+
"@blocklet/pages-kit-block-studio": "^0.7.17"
|
|
206
206
|
},
|
|
207
207
|
"devDependencies": {
|
|
208
208
|
"@trivago/prettier-plugin-sort-imports": "^5.2.1",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";const u=require("./components-aaduHC9E.js"),G=require("@syncedstore/core"),it=require("yjs"),ct=require("@blocklet/pages-kit/utils/data-source"),se=require("@blocklet/pages-kit/utils/route"),lt=require("lodash/cloneDeep"),h=require("sequelize");require("sqlite3");const ut=require("@blocklet/sdk/lib/config"),_=require("ufo"),Be=require("lodash");require("crypto");const Z=require("fs"),pt=require("p-limit"),p=require("path"),dt=require("worker_threads"),Ue=require("@blocklet/pages-kit/utils/common"),ft=require("@blocklet/pages-kit/utils/page-model"),gt=require("@blocklet/pages-kit/utils/property"),Ee=require("@blocklet/sdk/lib/component"),mt=require("@reactivedata/reactive"),D=require("fs/promises"),oe=require("glob"),ht=require("lib0/decoding"),yt=require("lib0/encoding"),St=require("lodash/debounce"),wt=require("lodash/get"),It=require("lodash/isEmpty"),bt=require("lodash/set"),Pt=require("lodash/union"),Ge=require("lru-cache"),jt=require("stream/promises"),Et=require("tar"),At=require("wait-on"),W=require("y-protocols/awareness"),fe=require("y-protocols/sync"),Dt=require("yaml"),$e=require("./html-dP5_4zu1.js");require("@blocklet/pages-kit/types/state");const M=t=>t&&t.__esModule?t:{default:t};function le(t){if(t&&t.__esModule)return t;const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(t){for(const a in t)if(a!=="default"){const s=Object.getOwnPropertyDescriptor(t,a);Object.defineProperty(e,a,s.get?s:{enumerable:!0,get:()=>t[a]})}}return e.default=t,Object.freeze(e)}const q=le(it),Ae=M(lt),E=M(ut),V=M(Z),De=M(pt),Ne=M(p),ge=le(ht),L=le(yt),Te=M(St),Re=M(wt),Oe=M(It),Me=M(bt),Tt=M(Pt),Rt=M(At),H=le(Dt),Ot=h.DataTypes.sqlite.DATE.parse;h.DataTypes.sqlite.DATE.parse=(t,e)=>typeof t=="number"?new Date(t):Ot(t,e);const F=new h.Sequelize({dialect:"sqlite",storage:u.databaseUrl,benchmark:process.env.ENABLE_SEQUELIZE_BENCHMARK==="true",retry:{match:[/SQLITE_BUSY/],name:"query",max:10},logging:process.env.ENABLE_SEQUELIZE_LOGGING==="true"?console.log:!1});F.query("PRAGMA journal_mode = WAL;");F.query("PRAGMA synchronous = normal;");F.query("PRAGMA journal_size_limit = 67108864;");F.query("PRAGMA cache_size = 10000;");process.on("SIGINT",async()=>{await F.close(),process.exit(0)});process.on("SIGTERM",async()=>{await F.close(),process.exit(0)});async function Ct(t,e){try{if(t.getDialect()!=="sqlite")return;const[a]=await t.query("SELECT 1");if(!a||a.length===0)return;await t.query("PRAGMA shrink_memory;")}catch(a){if(a.name==="SequelizeConnectionError"||a?.message&&/closed!/.test(a.message))return;console.error("Failed to cleanup SQLite memory",e,a)}}let Se=null;Se&&clearInterval(Se);Se=setInterval(async()=>{u.logger.info("Start cleanupSqliteMemory"),await Ct(F,u.databaseUrl),u.logger.info("End cleanupSqliteMemory")},60*1e3*10);const kt="z8iZiDFg3vkkrPwsiba1TLXy3H9XHzFERsP8o",we="page",Ie="trigger-reload-project-resource",Ce=kt,Lt="z2qa7BQdkEb3TwYyEYC1psK6uvmGnHSUHt5RM",vt="z8iZiDFg3vkkrPwsiba1TLXy3H9XHzFERsP8o";class ke extends h.Model{}ke.init({id:{type:h.DataTypes.UUID,allowNull:!1,primaryKey:!0,defaultValue:h.DataTypes.UUIDV4},projectId:{type:h.DataTypes.UUID,allowNull:!1},componentId:{type:h.DataTypes.STRING,allowNull:!1}},{sequelize:F,tableName:"ProjectComponents",timestamps:!1});const _t="SLUG_INVALID",Y=t=>({error:"slugInvalid",code:_t,field:"slug",message:t}),Ut={error:"slugRequired",code:"SLUG_REQUIRED",field:"slug",message:()=>"Project slug is required"},$t={error:"slugAlreadyExists",code:"SLUG_EXISTS",field:"slug",message:t=>`Project slug "${t}" already exists`},Nt=[/\.\./,/<[^>]*>/,/%[0-9a-f]{2}/i,/[<>'"%;{}()\\]/,/\x00/,/\n|\r|\t|\v|\f/,/[^a-zA-Z0-9-_@/\\:]/],Fe=t=>{if(!t)return"";if(t==="/")return"/";const e=_.withoutTrailingSlash(t);return _.withLeadingSlash(e)||"/"},Mt=t=>t.did===vt;class $ extends h.Model{static async getProjectByIdOrSlug(e,a){return e?$.findOne({where:{[h.Op.or]:[{id:e},{slug:e}],...a?.createdBy?{createdBy:a.createdBy}:{}}}):null}static async validateProjectSlug({slug:e,projectId:a}){if(e==null)return null;if(e==="")return Ut;const s=e==="/"?"/":_.withoutTrailingSlash(_.withLeadingSlash(e)),o=Fe(s);if(s!=="/"&&s.endsWith("/"))return Y(r=>`Project slug "${r}" cannot end with /`);if(/\/{2,}/.test(s))return Y(r=>`Project slug "${r}" cannot contain consecutive /`);if(/\s/.test(s))return Y(r=>`Project slug "${r}" cannot contain whitespace`);if(Nt.some(r=>r.test(s)))return Y(r=>`Project slug "${r}" contains invalid characters`);if(E.default.components?.filter(r=>r.mountPoint&&!Mt(r)).some(r=>Fe(r.mountPoint)===o))return Y(r=>`Project slug "${r}" conflicts with existing blocklet`);const l=await $.findOne({where:{slug:s}});return l&&l?.id!==a?$t:null}}$.init({id:{type:h.DataTypes.UUID,defaultValue:h.DataTypes.UUIDV4,primaryKey:!0},name:{type:h.DataTypes.STRING,allowNull:!1},description:h.DataTypes.TEXT,createdAt:h.DataTypes.DATE,updatedAt:h.DataTypes.DATE,createdBy:{type:h.DataTypes.STRING,allowNull:!1},updatedBy:{type:h.DataTypes.STRING,allowNull:!1},slug:h.DataTypes.STRING,icon:h.DataTypes.STRING,pinnedAt:h.DataTypes.DATE,useAllResources:h.DataTypes.BOOLEAN,npmSecret:h.DataTypes.STRING,relatedBlocklets:{type:h.DataTypes.JSON,allowNull:!1,defaultValue:{},get(){const t=this.getDataValue("relatedBlocklets");if(typeof t=="object")return t??{};try{return t?JSON.parse(t):{}}catch(e){return u.logger.error("Failed to parse relatedBlocklets",{error:e,rawValue:t}),{}}},set(t){try{this.setDataValue("relatedBlocklets",t?JSON.stringify(t):"{}")}catch(e){u.logger.error("Failed to set relatedBlocklets",{error:e,value:t}),this.setDataValue("relatedBlocklets","{}")}}},productionState:{type:h.DataTypes.JSON,allowNull:!1,defaultValue:{},get(){const t=this.getDataValue("productionState");if(typeof t=="object")return t??{};try{return t?JSON.parse(t):{}}catch(e){return u.logger.error("Failed to parse productionState",{error:e,rawValue:t}),{}}},set(t){try{this.setDataValue("productionState",t?JSON.stringify(t):"{}")}catch(e){u.logger.error("Failed to set productionState",{error:e,value:t}),this.setDataValue("productionState","{}")}}},meta:{type:h.DataTypes.JSON,allowNull:!0}},{sequelize:F,paranoid:!0,indexes:[{name:"projects_slug_unique",unique:!0,fields:["slug"]},{name:"projects_created_by",fields:["createdBy"]},{name:"projects_pinned_updated_meta_not_null",fields:[{name:"pinnedAt",order:"DESC"},{name:"updatedAt",order:"DESC"}],where:{meta:{[h.Op.ne]:null}}}]});$.hasMany(ke,{foreignKey:"projectId",as:"components"});async function x(t){try{return await V.default.promises.access(t,V.default.constants.F_OK),!0}catch{return!1}}function Ve(t,e){return new Promise((a,s)=>{const o=V.default.createReadStream(t),n=V.default.createWriteStream(e);o.on("error",s),n.on("error",s),n.on("finish",a),o.pipe(n)})}async function ze(t,e){await V.default.promises.mkdir(e,{recursive:!0});const a=await V.default.promises.readdir(t,{withFileTypes:!0});for(const s of a){const o=Ne.default.join(t,s.name),n=Ne.default.join(e,s.name);s.isDirectory()?await ze(o,n):await Ve(o,n)}}async function Ft(t,e){(await V.default.promises.stat(t)).isDirectory()?await ze(t,e):await Ve(t,e)}class ee extends h.Model{}ee.init({id:{type:h.DataTypes.UUID,primaryKey:!0,defaultValue:h.DataTypes.UUIDV4},projectId:{type:h.DataTypes.UUID,allowNull:!1,comment:"Project ID"},urlPath:{type:h.DataTypes.STRING(512),allowNull:!1,unique:!0,comment:"URL path, e.g. /project-slug/page-slug or /en/project-slug/page-slug"},projectSlug:{type:h.DataTypes.STRING,allowNull:!0,comment:"Project slug"},pageSlug:{type:h.DataTypes.STRING,allowNull:!1,comment:"Page slug"},pageId:{type:h.DataTypes.UUID,allowNull:!1,comment:"Page ID"},routeId:{type:h.DataTypes.UUID,allowNull:!0,comment:"Route ID (for draft mode)"},locale:{type:h.DataTypes.STRING(10),allowNull:!0,comment:"Locale code, e.g. en, zh"},defaultLocale:{type:h.DataTypes.STRING(10),allowNull:!0,comment:"Default locale"},shouldRedirect:{type:h.DataTypes.BOOLEAN,defaultValue:!1,comment:"Whether this URL should redirect"},mainPage:{type:h.DataTypes.BOOLEAN,defaultValue:!1,comment:"Whether this is the main page"},isPublic:{type:h.DataTypes.BOOLEAN,allowNull:!1,defaultValue:!0,comment:"Whether the page is public"},publishedAt:{type:h.DataTypes.BIGINT,allowNull:!0,comment:"Published timestamp"},locales:{type:h.DataTypes.JSON,allowNull:!0,comment:"Supported locales array"},createdAt:h.DataTypes.DATE,updatedAt:h.DataTypes.DATE},{sequelize:F,tableName:"PageUrlMappings",timestamps:!0,indexes:[{name:"idx_project_id",fields:["projectId"]},{name:"idx_url_path",unique:!0,fields:["urlPath"]},{name:"idx_page_id",fields:["pageId"]}]});function qt(t){const{projectId:e,projectSlug:a,state:s}=t,o=a||e,n=Be.union(E.default.env.languages?.map(c=>c.code)||[],s.supportedLocales?.map(c=>c.locale)||[]),l={},r=(c,S)=>{o&&(l[_.joinURL("/",o,c)]={...S,shouldRedirect:!0,mainPage:!0}),l[_.joinURL("/",e,c)]={...S,shouldRedirect:!0,mainPage:!0};for(const j of n){const T={...S,locale:j};l[_.joinURL("/",j,e,c)]=T,o&&(l[_.joinURL("/",j,o,c)]=T)}};for(const c of s.pageIds||[]){const S=s.pages?.[c];if(!S||!S.isPublic)continue;const j={projectId:e,projectSlug:o,pageSlug:S.slug,pageId:c,defaultLocale:n?.[0],locales:n,publishedAt:s.config?.publishedAt,isPublic:S.isPublic};r(S.slug,j)}return l}async function xt(t,e,a){const s=t.map(n=>n.urlPath),o=await ee.findAll({where:{urlPath:{[h.Op.in]:s},projectId:{[h.Op.ne]:e}},attributes:["urlPath","projectId","projectSlug","pageSlug"],transaction:a,raw:!0});if(o.length>0){u.logger.warn(`[URL Duplicate Warning] Found ${o.length} URL conflicts for project ${e}:`);for(const n of o){const l=t.find(r=>r.urlPath===n.urlPath);if(l){const r=n.projectSlug?_.joinURL(n.projectSlug,n.pageSlug):n.pageSlug;u.logger.warn(` - URL "${n.urlPath}" conflicts with project ${n.projectId} (${r}). Current project trying to use same URL for page: ${l.pageSlug}`)}}u.logger.warn("[URL Duplicate Warning] These duplicate URLs will be ignored during save. Consider using different project slugs or page slugs to avoid conflicts.")}}async function Bt(t){const{projectId:e,transaction:a}=t;try{await ee.destroy({where:{projectId:e},transaction:a});const s=qt(t),o=Object.entries(s).map(([n,l])=>({projectId:e,urlPath:n,projectSlug:l.projectSlug,pageSlug:l.pageSlug,pageId:l.pageId,routeId:l.routeId,locale:l.locale,defaultLocale:l.defaultLocale,shouldRedirect:l.shouldRedirect,mainPage:l.mainPage,isPublic:l.isPublic,publishedAt:typeof l.publishedAt=="number"?l.publishedAt:void 0,locales:l.locales}));if(o.length>0){await xt(o,e,a);const n=100,l=[];for(let r=0;r<o.length;r+=n){const c=o.slice(r,r+n);l.push(ee.bulkCreate(c,{transaction:a,ignoreDuplicates:!0}))}await Promise.all(l),u.logger.info(`Regenerated ${o.length} URL mappings for project ${e}`)}return o.length}catch(s){throw u.logger.error(`Failed to regenerate URL mappings for project ${e}:`,s),s}}function ne(t){t.observeDeep(e=>{e.some(a=>a.changes.keys.has("updatedAt")||a.changes.keys.has("publishedAt"))||t.set("updatedAt",new Date().toISOString())})}function He(){return Z.mkdtempSync(p.join(E.default.env.dataDir,"tmp-"))}function re(t,e,a=[]){return Array.isArray(t)?t.flatMap((s,o)=>re(s,e,[...a,o])):typeof t=="object"?t===null?[]:Object.entries(t).flatMap(([s,o])=>re(o,e,[...a,s])):e(t)?[a]:[]}function U(t){return t.filter(e=>e!=null)}function Gt(t){return new Promise((e,a)=>{let s;process.env.NODE_ENV==="development"?s=p.join(__dirname,"yaml-worker.js"):s=p.join(__dirname,"api/dist/utils/yaml-worker.js");const o=new dt.Worker(s);o.postMessage({payload:t}),o.on("message",n=>{n.status==="success"?e(n.result):a(new Error(`YAML stringify failed in worker: ${n.message}`)),o.terminate()}),o.on("error",n=>{a(n)}),o.on("exit",n=>{n!==0&&a(new Error(`Worker stopped with exit code ${n}`))})})}function Vt(t){t.pages&&Object.keys(t.pages).forEach(a=>{const s=G.getYjsValue(t.pages[a]);s&&s instanceof q.Map&&ne(s)});const e=G.getYjsValue(t.pages);e&&e instanceof q.Map&&e.observe(a=>{a.changes.keys.forEach((s,o)=>{if(s.action==="add"){const n=G.getYjsValue(t.pages[o]);n&&n instanceof q.Map&&ne(n)}})})}function zt(t){t.routes&&Object.keys(t.routes).forEach(a=>{const s=G.getYjsValue(t.routes?.[a]);s&&s instanceof q.Map&&ne(s)});const e=G.getYjsValue(t.routes);e&&e instanceof q.Map&&e.observe(a=>{a.changes.keys.forEach((s,o)=>{if(s.action==="add"){const n=G.getYjsValue(t.routes?.[o]);n&&n instanceof q.Map&&ne(n)}})})}function Ht(t,e){for(const a of e||Object.keys(t.routes||{})){let s=a,o=[];if(a.includes("-")){const[n,...l]=a.split("-");s=n,o=l||[]}if(t.routes?.[s]!==void 0){t.routes[s].publishedAt=new Date().toISOString();const n=t.routes[s];if(!n||!n.params||n.params.length===0)continue;if(a.includes("-")&&o.length>0){const l=se.getRouteMetaDataByOptionIds(o,n);l&&(l.publishedAt=new Date().toISOString())}if(!e){const l=se.generateParamCombinations({basePath:n.path,params:n.params,routeId:n.id,paramsOptions:n.paramsOptions,currentIndex:0,currentParams:[],currentOptionIds:[],result:[]});for(const r of l)r.routeMetaData??={},r.routeMetaData.publishedAt=new Date().toISOString()}}}}function me({page:t,route:e,state:a,routeId:s,routePathInfo:o}){u.logger.info(`Executing datasource data assembly, routeId: ${s}, routePathInfo: ${JSON.stringify(o)}`);const n={...Ae.default(t),id:s,slug:o?.path??e.path,createdAt:e.createdAt,updatedAt:o?.routeMetaData?.updatedAt??e.updatedAt,publishedAt:o?.routeMetaData?.publishedAt??e.publishedAt,isPublic:(o?.routeMetaData?.isPublic??e.isPublic)&&e.isPublic};for(const l of a.supportedLocales){if(e.dataSource){let r=e.id;o&&(r=o.paramOptionIds.join("-"));const c=e.dataSource.pathDataMappings?.[r]?.dataCache?.[l.locale]??e.dataSource.pathDataMappings?.[r]?.dataCache?.[a.config.defaultLocale||"en"];if(!c)continue;ct.setPageDataSource(n,a,l.locale,c)}o&&o.routeMetaData&&(o.routeMetaData.publishedAt=new Date().toISOString())}return n}["true","1","yes","y"].includes(process.env.USE_FS_CACHE_HTML??"");const Kt=60*60*1e3,J=new Ge.LRUCache({max:300,ttl:Kt,ttlResolution:10*1e3,allowStale:!0});function Wt(t,e=[]){let a=0;const s=Array.from(J.keys()),o=t.map(n=>_.withoutTrailingSlash(n));for(const n of s)for(const l of o){if($e.matchCacheKey(n,{currentPath:l})){J.delete(n),a++,u.logger.info(`[Cache CLEAR] key: ${n}`);break}for(const r of e)if($e.matchCacheKey(n,{currentPath:`/${r}${l}`})){J.delete(n),a++,u.logger.info(`[Cache CLEAR] key: ${n}`);break}}return u.logger.info(`[Cache CLEAR] cleared ${a} entries for paths:`,o),a}function Yt(){const t=J.size;return J.clear(),u.logger.info(`[Cache CLEAR ALL] cleared ${t} entries`),t}const Jt=Be.debounce(Yt,300);E.default.events.on(E.default.Events.envUpdate,Jt);const{uploadToMediaKit:Xt}=require("@blocklet/uploader-server"),Le=/^\w+(\w|-|\.)+\w+\.(jpe?g|png|gif|svg|bmp|webp|mp4|m4v|webm)$/,X=/mediakit:\/\/([a-f0-9]{32}\.(jpe?g|png|gif|svg|bmp|webp|mp4|m4v|webm))/i,qe=/mediakit:\/\/([a-f0-9]{32}\.(jpe?g|png|gif|svg|bmp|webp|mp4|m4v|webm))/gi,Qt=1e4,Zt=3e4,te=0,he=1,ea=0,ta=1,be=E.default,z=p.join(process.env.BLOCKLET_DATA_DIR,"site-state"),aa=["production","draft"],sa=["production"];function ie(t){return t?.replace(/\//g,"|")||""}function Ke(){const t=be.env.languages?.map(a=>({locale:a.code,name:a.name}))||[],e=t[0]?.locale||"en";return{pageIds:[],pages:{},routeIds:[],routes:{},dataSourceIds:[],dataSources:{},components:{},supportedLocales:t,config:{defaultLocale:e},resources:{}}}class C extends q.Doc{constructor(e){super(),this.options=e,Z.existsSync(this.draftYjsFilePath)&&q.applyUpdate(this,Z.readFileSync(this.draftYjsFilePath)),this.syncedStore=mt.reactive(G.syncedStore({pages:{},pageIds:[],components:{},supportedLocales:[],config:{},resources:{},routeIds:[],routes:{},dataSourceIds:[],dataSources:{}},this)),this.initObserver(),this.on("update",this.updateHandler),this.awareness=new W.Awareness(this),this.awareness.on("update",this.awarenessChangeHandler),this.ensureDataStructure()}static RELEASE_DELAY=5*60*1e3;static PERIODIC_CHECK_INTERVAL=2*60*60*1e3;static sharedInstances={};static periodicCheckTimer;static async safeDeleteProjectStateDir(e){if(!e)throw new Error("Should provide project context");try{const a=p.join(z,e),s=p.join(z,`@del-${e}`);await D.rename(a,s)}catch(a){u.logger.error("Failed to safe delete project state dir:",a)}}static async getProjectIds(){return(await $.findAll({attributes:["id"],raw:!0}))?.map(e=>e.id)}static get projectIds(){return oe.globSync("*/",{cwd:z,ignore:["@del-*","@tmp-*",".*","staging","production","@backup-*","undefined"]})}static get allShared(){return this.projectIds.map(e=>C.shared(e))}static shared(e){if(!e)throw new Error("Should provide project context");let a=C.sharedInstances[e];return a||(a=new C({path:p.join(z,e)}),C.sharedInstances[e]=a,a)}static async getProductionState(e){const a=await $.findByPk(e,{attributes:["productionState"]});if(Oe.default(a?.productionState)){const s=p.join(z,e,"production"),o=await ve(s,{includeResources:!0})??Ke();if(!o?.config?.defaultLocale){o.config??={};const n=be.env.languages?.map(l=>({locale:l.code,name:l.name}))||[];o.config.defaultLocale=n[0]?.locale}return o}return a?.productionState}destroy(){this.cancelRelease(),this.save({flush:!0}),this.conns.forEach((a,s)=>this.closeConn(s)),this.awareness.destroy();const e=p.basename(this.options.path);delete C.sharedInstances[e],super.destroy()}initObserver(){Vt(this.syncedStore),zt(this.syncedStore)}get draftYjsFilePath(){return p.join(this.options.path,"draft.yjs")}static async getStateByProjectId({projectId:e,mode:a,clone:s=!0}){if(a==="draft"){const o=C.shared(e);return s?JSON.parse(JSON.stringify(o.syncedStore)):o.syncedStore}return C.getProductionState(e)}async getState(e){if(e==="draft")return JSON.parse(JSON.stringify(this.syncedStore));const a=p.basename(this.options.path);return C.getProductionState(a)}async setState(e,a){if(e==="production"){const n=p.basename(this.options.path),l=Ae.default(a);await F.transaction(async r=>{await $.update({productionState:l},{where:{id:n},transaction:r});const c=await $.findByPk(n,{attributes:["slug"],transaction:r}),S=await Bt({projectId:n,projectSlug:c?.slug,state:a,transaction:r});u.logger.info(`[SiteState] saved ${S} URL mappings for project ${n}`)}),await this.clearPageCacheForRoutes(void 0,a)}const s=await Xe(a,{exportAssets:!1,includeResources:!0}),o=this.getPublishDir(e);await D.mkdir(p.dirname(o),{recursive:!0}),await D.rm(o,{force:!0,recursive:!0}),await D.rename(s,o)}getPublishDir(e){return p.join(this.options.path,e)}syncedStore;conns=new Map;awareness;releaseTimer;awarenessChangeHandler=({added:e,updated:a,removed:s},o)=>{const n=e.concat(a,s);if(o!==null){const c=this.conns.get(o);c&&(e.forEach(S=>{c.add(S)}),s.forEach(S=>{c.delete(S)}))}const l=L.createEncoder();L.writeVarUint(l,he),L.writeVarUint8Array(l,W.encodeAwarenessUpdate(this.awareness,n));const r=L.toUint8Array(l);this.conns.forEach((c,S)=>this.send(S,r))};updateHandler=e=>{const a=L.createEncoder();L.writeVarUint(a,te),fe.writeUpdate(a,e);const s=L.toUint8Array(a);this.conns.forEach((o,n)=>this.send(n,s))};ensureDataStructure=()=>{this.transact(()=>{const{supportedLocales:e,pages:a,pageIds:s,config:o,routes:n,routeIds:l}=this.syncedStore;{const r=new Set(Object.keys(a));let c=0;for(;c<s.length;){const S=s[c];r.has(S)?(r.delete(S),c++):s.splice(c,1)}}{const r=new Set(Object.keys(n));let c=0;for(;c<l.length;){const S=l[c];r.has(S)?(r.delete(S),c++):l.splice(c,1)}}e.splice(0,e.length),e.push(...be.env.languages.map(r=>({locale:r.code,name:r.name}))),o.defaultLocale=e[0]?.locale;{let r=0;const c=new Set;for(;r<e.length;){const{locale:S}=e[r];c.has(S)?e.splice(r,1):(r++,c.add(S))}}})};send=(e,a)=>{e.readyState!==ea&&e.readyState!==ta&&this.closeConn(e);try{e.send(a,s=>{s&&this.closeConn(e)})}catch{this.closeConn(e)}};closeConn=e=>{if(e.removeAllListeners(),this.conns.has(e)){const a=this.conns.get(e);this.conns.delete(e),a&&W.removeAwarenessStates(this.awareness,Array.from(a),null)}e.close(),this.checkAndScheduleRelease()};checkAndScheduleRelease(){this.conns.size===0&&this.scheduleRelease()}scheduleRelease(){this.cancelRelease();const e=p.basename(this.options.path);this.releaseTimer=setTimeout(()=>{u.logger.info(`[SiteState] releasing instance due to no active connections: ${e}`),this.conns.size===0&&(this.releaseTimer=void 0,this.destroy())},C.RELEASE_DELAY),u.logger.info(`[SiteState] scheduled release for project ${e} in ${C.RELEASE_DELAY/1e3}s`)}cancelRelease(){if(this.releaseTimer){clearTimeout(this.releaseTimer),this.releaseTimer=void 0;const e=p.basename(this.options.path);u.logger.info(`[SiteState] cancelled scheduled release for project ${e}`)}}autoSave=Te.default(async()=>{await D.mkdir(p.dirname(this.draftYjsFilePath),{recursive:!0}),await D.writeFile(this.draftYjsFilePath,q.encodeStateAsUpdate(this))},Qt);save=({flush:e=!1}={})=>{this.autoSave(),e&&this.autoSave.flush()};publish=async({mode:e,routes:a})=>{const s=p.basename(this.options.path);await nt(s);const o=await this.getState("draft"),n=await this.getState("production");await je(o,n,{routes:a,mergeMode:"replace",deleteRoutes:!0,publishMode:e}),n.config.publishedAt=new Date().getTime(),setImmediate(()=>{this.transact(()=>{Ht(this.syncedStore,a)})}),await this.setState(e,n)};mergeState=async(e,a)=>{const s=JSON.parse(JSON.stringify(a));e.config.fontFamily??={};const o=s.config?.fontFamily,n=e.config?.fontFamily;e.config.fontFamily.title=o?.title||n?.title,e.config.fontFamily.description=o?.description||n?.description,await new Promise((l,r)=>{this.transact(async()=>{try{const c=await je(e,a);l(c)}catch(c){r(c)}})})};clearPageCacheForRoutes=async(e,a)=>{const s=p.basename(this.options.path),n=(await $.findByPk(s))?.slug||s;let l=e;(!l||l.length===0)&&(l=a.pageIds??[]),u.logger.info(`[SiteState] clearing page cache for project ${s}, routes:`,l||[]);const r=a.supportedLocales.map(j=>j.locale),c=[],S=l.filter(j=>a.pageIds?.includes(j));for(const j of S){const b=a.pages[j].slug;n&&n!==s&&(n==="/"?c.push(b):c.push(`${n.startsWith("/")?"":"/"}${n}${b}`)),c.push(`/${s}${b}`)}if(c.length>0)try{const j=Wt(c,r);u.logger.info(`[SiteState] cleared ${j} page cache entries for project ${s}, routes:`,l)}catch{}};addConnection=e=>{if(this.conns.has(e))return;this.cancelRelease(),e.binaryType="arraybuffer",this.conns.set(e,new Set),e.on("message",o=>this.messageListener(e,new Uint8Array(o)));let a=!0;const s=setInterval(()=>{if(!a)this.conns.has(e)&&this.closeConn(e),clearInterval(s);else if(this.conns.has(e)){a=!1;try{e.ping()}catch{this.closeConn(e),clearInterval(s)}}},Zt);e.on("close",()=>{this.closeConn(e),clearInterval(s)}),e.on("pong",()=>{a=!0});{const o=L.createEncoder();L.writeVarUint(o,te),fe.writeSyncStep1(o,this),this.send(e,L.toUint8Array(o));const n=this.awareness.getStates();if(n.size>0){const l=L.createEncoder();L.writeVarUint(l,he),L.writeVarUint8Array(l,W.encodeAwarenessUpdate(this.awareness,Array.from(n.keys()))),this.send(e,L.toUint8Array(l))}}};messageListener=(e,a)=>{try{const s=L.createEncoder(),o=ge.createDecoder(a),n=ge.readVarUint(o);switch(u.logger.info(`[SiteState] messageListener, messageType: ${n}`),n){case te:L.writeVarUint(s,te),fe.readSyncMessage(o,s,this,null),u.logger.info(`[SiteState] messageListener, encoder length: ${L.length(s)}`),L.length(s)>1&&(this.ensureDataStructure(),this.send(e,L.toUint8Array(s)));break;case he:{W.applyAwarenessUpdate(this.awareness,ge.readVarUint8Array(o),e);break}default:u.logger.warn(`Unsupported messageType ${n}`)}}catch(s){u.logger.error(s)}this.save()};static async pageUrlMap(e,a){if(u.logger.info(`[SiteState] get pageUrlMap, mode: ${e}, projectId: ${a}`),e==="production"){const n=a?{projectId:a}:{},l=await ee.findAll({where:n,raw:!0}),r={};for(const c of l)r[c.urlPath]={projectId:c.projectId,projectSlug:c.projectSlug,pageSlug:c.pageSlug,pageId:c.pageId,routeId:c.routeId,locale:c.locale,defaultLocale:c.defaultLocale,shouldRedirect:c.shouldRedirect,mainPage:c.mainPage,isPublic:c.isPublic,publishedAt:c.publishedAt,locales:c.locales};return u.logger.info(`[SiteState] loaded ${l.length} URL mappings from database`),r}let s=[];a?s=[a]:s=await this.getProjectIds();let o={};if(s?.length){u.logger.info("[SiteState] find project infos from database, projectIds: ",s);const n=30,l=De.default(5);for(let r=0;r<s.length;r+=n){const c=s.slice(r,r+n);u.logger.info(`[SiteState] processing project batch ${r/n+1}, ids: `,c);const S=await $.findAll({where:{id:{[h.Op.in]:c}},attributes:{exclude:["relatedBlocklets"]}});await Promise.all(S?.map(j=>l(async()=>{const T=j.id,b=j.slug||T,m={},d=await C.getStateByProjectId({projectId:j.id,mode:e,clone:!1}),P=Tt.default(E.default.env.languages?.map(A=>A.code)||[],d.supportedLocales?.map(A=>A.locale)||[]),R=(A,I)=>{b&&(m[_.joinURL("/",b,A)]={...I,shouldRedirect:!0,mainPage:!0}),m[_.joinURL("/",T,A)]={...I,shouldRedirect:!0,mainPage:!0};for(const k of P){const y={...I,locale:k};m[_.joinURL("/",k,T,A)]=y,b&&(m[_.joinURL("/",k,b,A)]=y)}};if(e==="draft")for(const A of d.routeIds||[]){const I=d?.routes?.[A];if(!I)continue;if(I.params&&I.params.length>0){const w=se.generateParamCombinations({basePath:I.path,params:I.params,routeId:I.id,paramsOptions:I.paramsOptions,currentIndex:0,currentParams:[],currentOptionIds:[],result:[]});for(const i of w){const f=i.path,g={projectId:T,projectSlug:b,pageSlug:f,pageId:I.displayTemplateId||"",routeId:A,defaultLocale:P?.[0],locales:P,publishedAt:d.config.publishedAt,isPublic:I.isPublic&&i?.routeMetaData?.isPublic};R(f,g)}}const k=I.path,y={projectId:T,projectSlug:b,pageSlug:k,pageId:I.displayTemplateId||"",routeId:A,defaultLocale:P?.[0],locales:P,publishedAt:d.config.publishedAt,isPublic:I.isPublic};R(k,y)}for(const A of d.pageIds||[]){const I=d.pages[A];if(!I)continue;const k=I.slug,y=j.slug||T,w={projectId:T,projectSlug:y,pageSlug:k,pageId:A,defaultLocale:P?.[0],locales:P,publishedAt:d.config.publishedAt,isPublic:I.isPublic,templateConfig:I.templateConfig};R(k,w)}o={...o,...m}})))}}return u.logger.info("[SiteState] success get pageUrlMap"),o}getDocumentSize(){return q.encodeStateAsUpdate(this).byteLength}static getInstancesSizeInfo(){const e=[];for(const[a,s]of Object.entries(C.sharedInstances)){const o=s.getDocumentSize();e.push({projectId:a,sizeInBytes:o,sizeInMB:`${(o/(1024*1024)).toFixed(2)} MB`,activeConnections:s.conns.size})}return e}static startPeriodicCheck(){this.periodicCheckTimer||(this.periodicCheckTimer=setInterval(()=>{this.performPeriodicCheck()},this.PERIODIC_CHECK_INTERVAL),u.logger.info(`[SiteState] periodic check started, interval: ${this.PERIODIC_CHECK_INTERVAL/(60*60*1e3)} hours`))}static stopPeriodicCheck(){this.periodicCheckTimer&&(clearInterval(this.periodicCheckTimer),this.periodicCheckTimer=void 0,u.logger.info("[SiteState] periodic check stopped"))}static performPeriodicCheck(){const e=Object.keys(C.sharedInstances).length,a=[],s=[];for(const[o,n]of Object.entries(C.sharedInstances))n.conns.size===0?a.push({projectId:o,instance:n}):s.push({projectId:o,connections:n.conns.size});if(u.logger.info(`[SiteState] periodic check summary: total instances: ${e}, with connections: ${s.length}, without connections: ${a.length}`),a.length>0){u.logger.info(`[SiteState] releasing ${a.length} instances without connections:`,a.map(n=>n.projectId));let o=0;for(const{projectId:n,instance:l}of a)try{u.logger.info(`[SiteState] releasing instance due to periodic check: ${n}`),l.destroy(),o++}catch(r){u.logger.error(`[SiteState] failed to release instance ${n} during periodic check:`,r)}u.logger.info(`[SiteState] periodic check completed: ${o}/${a.length} instances released successfully`)}else e>0?u.logger.debug("[SiteState] periodic check: all instances have active connections"):u.logger.debug("[SiteState] periodic check: no instances exist")}}async function oa(t,e,a){if(!t||!await x(t)||!(await D.lstat(t)).isFile())return null;let o=a[t];return o||(o=(async()=>{try{return(await Xt({filePath:t,fileName:e}))?.data?.filename}catch(n){return u.logger.error(`Failed to upload asset ${t}:`,n),null}})(),a[t]=o),o}const We=async(t,e)=>{const a=p.basename(t),s=await Ee.call({name:Ce,path:_.joinURL("/uploads",a),responseType:"stream",method:"GET"});if(s.status>=200&&s.status<400){const o=Z.createWriteStream(e);await jt.pipeline(s.data,o)}else throw new Error(`download asset failed ${s.status}`)},Ye=async(t,e)=>{await Promise.all(t.map(async a=>{try{await We(a,p.join(e,p.basename(a)))}catch(s){u.logger.error(`Failed to export assets: ${a}, ${s}`)}}))};function Je(t){return Le.test(t)?[t]:X.test(t)?(qe.lastIndex=0,Array.from(t.matchAll(qe)).map(a=>a[1]).filter(a=>!!a)):[]}async function ae(t,e,a){const{getFilename:s,exportAssets:o,useWorker:n}=a,l=p.join(e,s(t));await D.mkdir(p.dirname(l),{recursive:!0});const r=n?await Gt(t):H.stringify(t);if(await D.writeFile(l,r),o){const S=re(t,j=>typeof j=="string"&&(Le.test(j)||X.test(j))).map(j=>{const T=Re.default(t,j);return Je(T)}).flat().filter(Boolean);await Ye(S,p.dirname(l))}}const Pe=new Ge.LRUCache({max:100,ttl:1*60*1e3});async function xe(t,e,a){const s=re(t,r=>typeof r=="string"&&(Le.test(r)||X.test(r))),o=De.default(2),n=s.map(r=>o(async()=>{try{const c=Re.default(t,r),S=Je(c);for(const j of S){const T=p.basename(j),b=a.getFilePath(j,r),m=b?`${b}:${T}`:T,d=Pe.get(m);if(d){X.test(c)||Me.default(t,r,d);return}const P=await oa(b,T,e);P&&(X.test(c)||Me.default(t,r,P),Pe.set(m,P))}}catch(c){u.logger.error(`Failed to process upload for path ${r.join(".")}:`,c.message||c.reason)}})),l=await Promise.allSettled(n);a.onFinish?.(l)}async function Xe(t,{exportAssets:e,pageIds:a="all",componentIds:s="all",rawConfig:o,includeResources:n=!1,routeIds:l="all"}={}){const r=a==="all"?t.pageIds:a,c=gt.getComponentDependencies({state:t,pageIds:r,componentIds:s==="all"?Object.keys(t.components):s});Object.entries(t.components).forEach(([i,f])=>{f.data?.renderer?.type==="component-template"&&c.push(i)});const S=l==="all"?t.routeIds:l,j=i=>({id:i.id,name:i.name,isTemplateSection:i.isTemplateSection??!1,templateDescription:i.templateDescription,component:i.component,config:i.config,visibility:i.visibility,sections:i?.sectionIds?U(i?.sectionIds?.map(f=>{const g=i.sections?.[f];return g&&j(g)})):void 0}),T=(i,f)=>({id:i.id,createdAt:i.createdAt,updatedAt:i.updatedAt,publishedAt:i.publishedAt,isPublic:i.isPublic??!0,templateConfig:i.templateConfig,meta:i.locales?.[f]??{},sections:U(i.sectionIds.map(g=>{const O=i.sections[g];return O&&j(O)})),dataSource:Object.fromEntries(Object.entries(i.dataSource||{}).map(([g,O])=>[g,O?.[f]??{}]))}),b=i=>({id:i.id,createdAt:i.createdAt,updatedAt:i.updatedAt,publishedAt:i.publishedAt,path:i.path,handler:i.handler,isPublic:i.isPublic??!0,params:i.params??[],enabledGenerate:i.enabledGenerate??!1,displayTemplateId:i.displayTemplateId,dataSource:i.dataSource}),m=U(S.map(i=>{const f=t.routes[i];return f&&b(f)})),d=U(t.supportedLocales.map(i=>i.locale).flatMap(i=>r.map(f=>{const g=t.pages[f];return g&&{locale:i,slug:g.slug,page:T(g,i)}}))),P=He(),R=p.join(P,"pages");await D.mkdir(R,{recursive:!0});const A=p.join(P,"components");await D.mkdir(A,{recursive:!0});const I=p.join(P,"routes");await D.mkdir(I,{recursive:!0});for(const{locale:i,slug:f,page:g}of d)await ae(g,R,{getFilename:()=>`${ie(f)||"index"}.${i}.yml`,exportAssets:e,useWorker:!0});for(const i of m)await ae(i,I,{getFilename:()=>`${ie(i.path)||"index"}.yml`,exportAssets:e});for(const i of c){const f=t.components[i]?.data;f&&await ae(f,A,{getFilename:g=>`${g.name||"unnamed"}.${g.id}.yml`,exportAssets:e})}const k=p.join(P,".blocklet/pages/pages.config.yml");await D.mkdir(p.dirname(k),{recursive:!0});const y={pages:U(r.map(i=>{const f=t.pages[i];return f&&{id:i,slug:f.slug}})),routes:U(S.map(i=>{const f=t.routes[i];return f&&{id:i,path:f.path}})),components:U(c.map(i=>{const f=t.components[i]?.data;return f&&{id:i,name:f.name}})),...n?{resources:{components:U(Object.keys(t.resources?.components||{}).filter(i=>c.includes(i)).map(i=>({id:i,name:t.resources?.components?.[i]?.component?.name})))}}:{},supportedLocales:t.supportedLocales,config:t.config};await D.writeFile(k,H.stringify(y));const w=p.join(P,"config.source.json");if(o&&await D.writeFile(w,JSON.stringify(o)),n){const i=p.join(P,"resources"),f=p.join(i,"components");await D.mkdir(f,{recursive:!0});for(const N of Object.keys(t?.resources?.components??{}).filter(v=>c.includes(v))){const v=t.resources?.components?.[N]?.component;v&&await ae(v,f,{getFilename:B=>`${B.name||"unnamed"}.${B.id}.yml`,exportAssets:e})}const g=p.join(P,"chunks");await D.mkdir(g,{recursive:!0});const O=await na();for(const N of Object.keys(t?.resources?.components??{}).filter(v=>c.includes(v))){const v=t.resources?.components?.[N]?.component;if(v&&v.renderer?.type==="react-component"){const B=v.renderer?.chunks??[];if(B?.length>0)for(const K of B){const _e=p.join(g,K),de=O?.[K];try{de&&await x(de)&&!await x(_e)&&await D.copyFile(de,_e)}catch(rt){u.logger.error(`copy chunk ${K} error`,rt.message)}}}}}return P}async function ve(t,{importAssets:e,includeResources:a}={}){if(!await x(t))return null;let s,o=!1;try{(await D.lstat(t)).isDirectory()?s=t:/\.(tgz|gz|tar)$/.test(t)&&(o=!0,s=He(),await Et.x({file:t,C:s}));const r=(await oe.glob("**/.blocklet/pages/pages.config.yml",{cwd:s,absolute:!0}))[0],c=r&&p.join(p.dirname(r),"../../pages"),S=r&&p.join(p.dirname(r),"../../components"),j=r&&p.join(p.dirname(r),"../../routes");if(!r)return null;const T=await D.readFile(r,"utf-8"),b=H.parse(T),m=async(y,w,i)=>{let f=p.join(y,`${w}${i?`.${i}`:""}.yml`);if(!await x(f)&&(f=p.join(y,w,`index${i?`.${i}`:""}.yml`),!await x(f))||!(await D.lstat(f)).isFile())return null;const O=await D.readFile(f,"utf-8");return H.parse(O)},d=async(y,w)=>{try{const f=(await oe.glob(`*.${w}.yml`,{cwd:y,absolute:!0}))[0];if(!f)return null;const g=await D.readFile(f,"utf-8");return H.parse(g)}catch(i){u.logger.error("parse component error",i)}return null},P=async(y,w)=>{let i=p.join(y,`${w}.yml`);if(!await x(i)&&(i=p.join(y,w,"index.yml"),!await x(i))||!(await D.lstat(i)).isFile())return null;const g=await D.readFile(i,"utf-8");return H.parse(g)},R=U(await Promise.all(b.pages.map(async({slug:y})=>{const w=U(await Promise.all(b.supportedLocales.map(async({locale:g})=>{const O=c?await m(c,ie(y),g):void 0;if(O)return{locale:g,page:O};const N=c?await m(c,y,g):void 0;return N&&{locale:g,page:N}}))),i=w[0]?.page;if(!i)return null;const f=i.sections.map(ft.unzipSection);return{id:i.id||Ue.nextId(),createdAt:i.createdAt,updatedAt:i.updatedAt,publishedAt:i.publishedAt,isPublic:i.isPublic??!0,templateConfig:i.templateConfig,slug:y,sections:Object.fromEntries(f.map(g=>[g.id,g])),sectionIds:f.map(g=>g.id),locales:Object.fromEntries(w.map(({locale:g,page:O})=>[g,O.meta])),dataSource:i.dataSource?Object.fromEntries([...new Set(w.flatMap(({page:g})=>Object.keys(g.dataSource??{})))].map(g=>[g,Object.fromEntries(w.map(({locale:O,page:N})=>{const v=N.dataSource?.[g];return[O,v||{}]}))])):Object.fromEntries([...new Set(w.flatMap(({page:g})=>g.sections.map(O=>O.id)))].map(g=>[g,Object.fromEntries(w.map(({locale:O,page:N})=>{const v=N.dataSource?.[g];if(v)return[O,v];const B=N.sections.find(K=>K.id===g);return[O,B?.properties||{}]}))]))}}))),A=U(await Promise.all((b?.routes||[]).map(async({path:y})=>{const w=j?await P(j,ie(y)):void 0;return{...w,id:w?.id||Ue.nextId(),createdAt:w?.createdAt??new Date().toISOString(),updatedAt:w?.updatedAt??new Date().toISOString(),publishedAt:new Date(0).toISOString(),path:w?.path??`/${w?.id}`,params:w?.params,handler:w?.handler??"Pages Kit",isPublic:w?.isPublic??!0,enabledGenerate:w?.enabledGenerate??!1,displayTemplateId:w?.displayTemplateId??void 0,dataSource:w?.dataSource??{}}}))),I=S?U(await Promise.all((b.components||[]).map(async({id:y})=>d(S,y)))):[];if(e){const y=(...w)=>{u.logger.info(`[${o?p.basename(t):p.basename(p.join(t,"../../../../"))}] importAssets:`,...w)};try{y("wait image-bin api ready"),await Rt.default({resources:[`${Ee.getComponentWebEndpoint(u.IMAGE_BIN_NAME)}/api/sdk/uploads`],validateStatus:f=>f>=200&&f<=500}),y("image-bin api is ready");const w={},i={};y("start to upload assets"),await Promise.allSettled([xe(I,w,{getFilePath:f=>S&&p.join(S,f),onFinish:f=>{y(`upload ${f.length} component assets`)}}),xe(R,i,{getFilePath:(f,g)=>{const O=Re.default(R,g.slice(0,1));return c&&p.join(c,p.dirname(O.slug),f)},onFinish:f=>{y(`upload ${f.length} page assets`)}})]),y("upload assets done"),Pe.clear(),global.gc&&global.gc()}catch(w){y("Error during asset import:",w)}}const k={};if(a){const y=r&&p.join(p.dirname(r),"../../resources/components"),w=U(await Promise.all((b.resources?.components||[]).map(async({id:i})=>d(y,i))));w.length>0&&(k.components=Object.fromEntries(w.map((i,f)=>[i.id,{index:f,component:i}])))}return{supportedLocales:b.supportedLocales,pageIds:R.map(y=>y.id),components:Object.fromEntries(I.map((y,w)=>[y.id,{index:w,data:y}])),pages:Object.fromEntries(R.map(y=>[y.id,y])),config:b.config||{},resources:k,routeIds:A.map(y=>y.id),routes:Object.fromEntries(A.map(y=>[y.id,y])),dataSourceIds:[],dataSources:{}}}finally{o&&s&&await D.rm(s,{force:!0,recursive:!0})}}async function je(t,e,{routes:a,mergeMode:s="byUpdateTime",deleteRoutes:o=!1,publishMode:n=void 0}={}){try{n&&u.clearPreloadComponentsCacheByMode(n)}catch(b){u.logger.error("clear preload page cache error",{error:b})}const{pages:l,pageIds:r,routeIds:c,routes:S,supportedLocales:j}=t;if(n==="production"){let b=a??[],m=null;for(const d of c??[]){const P=S?.[d];if(P?.params&&P?.params.length>0&&P?.paramsOptions&&P?.paramsOptions.length>0){const R=se.generateParamCombinations({basePath:P.path,params:P.params,routeId:P.id,paramsOptions:P.paramsOptions,currentIndex:0,currentParams:[],currentOptionIds:[],result:[]}),A=Object.fromEntries(R.map(I=>[`${d}-${I.paramOptionIds.join("-")}`,I]));m={...m||{},...A},a||(b=[...b,...R.map(I=>`${d}-${I.paramOptionIds.join("-")}`)])}else a||b.push(d)}u.logger.info("routeIds to be published: ",b);for(const d of b){let P=d;if(P.includes("-")){const[I]=P.split("-");P=I}const R=S?.[P];if(!R){const I=e.pageIds.indexOf(P);I!==-1&&o&&(e.pageIds.splice(I,1),delete e.pages[P]);for(const k of e.pageIds)k.includes(`${P}-`)&&(e.pageIds.splice(e.pageIds.indexOf(k),1),delete e.pages[k]);u.logger.info("delete main route page",P);continue}if(d.includes("-")&&!m?.[d]){const I=e.pageIds.indexOf(d);I!==-1&&o&&(e.pageIds.splice(I,1),delete e.pages[d]),u.logger.info("delete page",d);continue}if(!R.displayTemplateId){u.logger.info("no display template",d);continue}const A=l[R.displayTemplateId];if(!A){u.logger.info("no template page",d);continue}if(e.pageIds.includes(d)){if(u.logger.info("has need update page",d),s==="replace")e.pages[d]=me({page:A,route:R,state:t,routeId:d,routePathInfo:m?.[d]}),u.logger.info("replace page",d);else if(s==="byUpdateTime"){const I=e.pages[R.id];(!I||R.updatedAt&&R.updatedAt>I.updatedAt)&&(e.pages[d]=me({page:A,route:R,state:t,routeId:d,routePathInfo:m?.[d]}),u.logger.info("replace page by update time",d))}}else e.pageIds.push(d),e.pages[d]=me({page:A,route:R,state:t,routeId:d,routePathInfo:m?.[d]}),u.logger.info("add page",d)}if(o&&!a)for(const d of e.pageIds)b?.includes(d)||(delete e.pages[d],u.logger.info("delete page",d)),e.pageIds=[...e.pageIds].filter(P=>b?.includes(P))}else{for(const b of r){const m=l[b];if(m)if(e.pageIds.includes(m.id)){if(s==="replace")e.pages[m.id]=m;else if(s==="byUpdateTime"){const d=e.pages[m.id];(!d||m.updatedAt&&m.updatedAt>d.updatedAt)&&(e.pages[m.id]=m)}}else e.pageIds.push(m.id),e.pages[m.id]=m}for(const b of c){const m=S[b];if(m)if(e.routeIds.includes(m.id)){if(s==="replace")e.routes[m.id]=m;else if(s==="byUpdateTime"){const d=e.routes[m.id];(!d||m.updatedAt&&m.updatedAt>d.updatedAt)&&(e.routes[m.id]=m)}}else e.routeIds.push(m.id),e.routes[m.id]=m}}if(e.supportedLocales.splice(0,e.supportedLocales.length),e.supportedLocales.push(...Ae.default(j)),o)for(const b of Object.keys(e.components))delete e.components[b];let T=JSON.parse(JSON.stringify(t.components));T=Object.fromEntries(await Promise.all(Object.entries(T).map(async([b,m])=>{const d=await Qe(m?.data);return[b,{...m,data:d}]}))),Object.assign(e.components,T),Object.assign(e.config,JSON.parse(JSON.stringify(t.config))),Oe.default(t.resources.components)||(e.resources.components=JSON.parse(JSON.stringify(t.resources.components||{})))}const Qe=u.memoizeWithFs(async t=>{if(!Oe.default(t?.properties))return t;if(t?.renderer?.type==="react-component"){const{script:e,PROPERTIES_SCHEMA:a}=t?.renderer||{};if(a||e&&e.includes("PROPERTIES_SCHEMA"))try{const s=await u.getExportSchemaValueFromCode(e??"","PROPERTIES_SCHEMA",t.id,a);s&&s.length>0&&t&&(t.properties={},s.forEach((o,n)=>{t?.properties&&(t.properties[o.id]={index:n,data:o})}))}catch(s){u.logger.error("getPropertiesFromCode error",{componentId:t.id,name:t.name},{error:s})}}return t},{subdir:"getPropertiesFromCode"});let ce,Q,ue,pe;const Ze=()=>Ee.getResources({types:[{did:Ce,type:we},{did:Lt,type:we}]}),na=async()=>{const t=Ze(),e={};for(const a of t){const o=(await oe.glob("**/.blocklet/pages/pages.config.yml",{cwd:a.path,absolute:!0}))[0],n=o&&p.join(p.dirname(o),"../../chunks");if(n&&await x(n)){const l=await D.readdir(n);for(const r of l)e[r]=p.join(n,r)}}return e};function et(){return ce=(async()=>{const t=Ze();Q=(await Promise.all(t.map(async a=>{const s=a.path?await ve(a.path,{importAssets:!1}):void 0;return s?{blockletId:a.did,state:s,blockletTitle:a.title}:void 0}))).filter(a=>!!a),ue=Q.reduce((a,s)=>Object.assign(a,Object.fromEntries(Object.values(s.state.pages).map(o=>o?[o?.id,{page:o,blockletId:s.blockletId}]:[]))),{});const e=Q.reduce((a,s)=>Object.assign(a,Object.fromEntries(Object.values(s.state.components).map(o=>[o.data.id,{blockletId:s.blockletId,component:o.data}]))),{});pe=Object.fromEntries(await Promise.all(Object.entries(e).map(async([a,s])=>{const o=await Qe(s.component);return[a,{...s,component:o}]})))})(),ce}function tt(t){const e=Te.default(async()=>{await et().catch(a=>{u.logger.error("load resource states error",{error:a})}),await t?.({states:Q,pages:ue,components:pe})},3e3,{leading:!1,trailing:!0});return e(),E.default.events.on(E.default.Events.componentAdded,e),E.default.events.on(E.default.Events.componentRemoved,e),E.default.events.on(E.default.Events.componentStarted,e),E.default.events.on(E.default.Events.componentStopped,e),E.default.events.on(E.default.Events.componentUpdated,e),E.default.events.on(Ie,e),()=>{E.default.events.off(E.default.Events.componentAdded,e),E.default.events.off(E.default.Events.componentRemoved,e),E.default.events.off(E.default.Events.componentStarted,e),E.default.events.off(E.default.Events.componentStopped,e),E.default.events.off(E.default.Events.componentUpdated,e),E.default.events.off(Ie,e)}}const at=Symbol.for("GLOBAL_RESOURCE_STATES_LISTENER_KEY"),st=globalThis;st[at]?.();st[at]=tt(async({pages:t,components:e})=>{const a=await C.getProjectIds();u.logger.info(`start update resource states projects(${a.length})`,a);const s=De.default(10);await Promise.race([new Promise(o=>{setTimeout(()=>{o({})},30*1e3)}),Promise.all(a.map(o=>s(async()=>{ot({projectId:o,pages:t,components:e})})))]).catch(o=>{u.logger.error("update resource states failed:",o)})});C.startPeriodicCheck();process.on("beforeExit",()=>{C.stopPeriodicCheck()});process.on("SIGINT",()=>{C.stopPeriodicCheck(),process.exit(0)});process.on("SIGTERM",()=>{C.stopPeriodicCheck(),process.exit(0)});async function ot({projectId:t,pages:e,components:a}){const s=C.sharedInstances[t];if(!s){u.logger.info(`projectId: ${t} not found in sharedInstances`);return}const o=await $.findByPk(t,{attributes:{exclude:["productionState","relatedBlocklets"]}});let n;if(o?.useAllResources)n=a;else{const r=(await ke.findAll({where:{projectId:t}})).map(c=>c.componentId);n=Object.fromEntries(Object.entries(a||{}).filter(([c])=>r.includes(c)))}s.transact(()=>{s.syncedStore.resources.pages=e,u.logger.info(`[${t}] pages resources updated: ${Object.keys(e||{}).length} pages`),s.syncedStore.resources.components=n,u.logger.info(`[${t}] components resources updated: ${Object.keys(n||{}).length} components`)}),u.logger.info(`update [${t}] resource states summary:`,{pages:Object.keys(s.syncedStore.resources.pages||{}).length,components:Object.keys(s.syncedStore.resources.components||{}).length})}const ye=new Map;async function nt(t){if(!ye.has(t)){const e=Te.default(async a=>ot({projectId:a,pages:ue,components:pe}),3e3);ye.set(t,e)}return ye.get(t)(t)}async function ra(){u.logger.info("trigger reload all project resource"),E.default.events.emit(Ie)}async function ia({ensureLoaded:t=!0}={}){return t&&(ce??=et(),await ce),{states:Q,pages:ue,components:pe}}exports.COMPONENT_DID=Ce;exports.PUBLISH_MODES=sa;exports.Project=$;exports.RESOURCE_TYPE=we;exports.SITE_STATE_PATH=z;exports.STATE_MODES=aa;exports.SiteState=C;exports.copyRecursive=Ft;exports.downloadAsset=We;exports.downloadAssets=Ye;exports.fromPackage=ve;exports.getDefaultState=Ke;exports.getResourceStates=ia;exports.initPackResourceStates=tt;exports.mergeState=je;exports.toPackage=Xe;exports.triggerReloadAllProjectResource=ra;exports.updateResourceStatesByProjectId=nt;
|