@blocklet/pages-kit-inner-components 0.7.2 → 0.7.3
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-D5CfLsg2.js +1 -0
- package/lib/cjs/resources.js +1 -1
- package/lib/cjs/site-state.js +1 -1
- package/lib/es/chunks/{site-state-21ffGEui.js → site-state-DY7YJ7F1.js} +143 -142
- package/lib/es/resources.js +1 -1
- package/lib/es/site-state.js +1 -1
- package/package.json +3 -3
- package/lib/cjs/chunks/site-state-DCRNxkS5.js +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const u=require("./components-CnPdZJ2Z.js"),G=require("@syncedstore/core"),rt=require("yjs"),it=require("@blocklet/pages-kit/utils/data-source"),ae=require("@blocklet/pages-kit/utils/route"),ct=require("lodash/cloneDeep"),lt=require("@blocklet/sdk/lib/config"),Z=require("fs"),f=require("path"),Me=require("@blocklet/pages-kit/utils/common"),ut=require("@blocklet/pages-kit/utils/page-model"),dt=require("@blocklet/pages-kit/utils/property"),Ae=require("@blocklet/sdk/lib/component"),pt=require("@reactivedata/reactive"),O=require("fs/promises"),se=require("glob"),ft=require("lib0/decoding"),gt=require("lib0/encoding"),mt=require("lodash/debounce"),ht=require("lodash/get"),yt=require("lodash/isEmpty"),St=require("lodash/set"),wt=require("lodash/union"),je=require("lru-cache"),It=require("p-limit"),A=require("sequelize"),bt=require("stream/promises"),Et=require("tar"),N=require("ufo"),Pt=require("wait-on"),H=require("y-protocols/awareness"),fe=require("y-protocols/sync"),At=require("yaml"),$e=require("./html-dP5_4zu1.js");require("sqlite3");require("@blocklet/pages-kit/types/state");const $=t=>t&&t.__esModule?t:{default:t};function ce(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 F=ce(rt),Oe=$(ct),E=$(lt),V=$(Z),Ne=$(f),ge=ce(ft),k=ce(gt),Ce=$(mt),De=$(ht),Te=$(yt),Fe=$(St),jt=$(wt),Re=$(It),Ot=$(Pt),K=ce(At),Ct=A.DataTypes.sqlite.DATE.parse;A.DataTypes.sqlite.DATE.parse=(t,e)=>typeof t=="number"?new Date(t):Ct(t,e);const B=new A.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});B.query("PRAGMA journal_mode = WAL;");B.query("PRAGMA synchronous = normal;");B.query("PRAGMA journal_size_limit = 67108864;");B.query("PRAGMA cache_size = 10000;");process.on("SIGINT",async()=>{await B.close(),process.exit(0)});process.on("SIGTERM",async()=>{await B.close(),process.exit(0)});async function Dt(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 Dt(B,u.databaseUrl),u.logger.info("End cleanupSqliteMemory")},60*1e3*10);const Tt="z8iZiDFg3vkkrPwsiba1TLXy3H9XHzFERsP8o",we="page",Ie="trigger-reload-project-resource",ve=Tt,Rt="z2qa7BQdkEb3TwYyEYC1psK6uvmGnHSUHt5RM",vt="z8iZiDFg3vkkrPwsiba1TLXy3H9XHzFERsP8o";class ke extends A.Model{}ke.init({id:{type:A.DataTypes.UUID,allowNull:!1,primaryKey:!0,defaultValue:A.DataTypes.UUIDV4},projectId:{type:A.DataTypes.UUID,allowNull:!1},componentId:{type:A.DataTypes.STRING,allowNull:!1}},{sequelize:B,tableName:"ProjectComponents",timestamps:!1});const kt="SLUG_INVALID",J=t=>({error:"slugInvalid",code:kt,field:"slug",message:t}),_t={error:"slugRequired",code:"SLUG_REQUIRED",field:"slug",message:()=>"Project slug is required"},Lt={error:"slugAlreadyExists",code:"SLUG_EXISTS",field:"slug",message:t=>`Project slug "${t}" already exists`},Ut=[/\.\./,/<[^>]*>/,/%[0-9a-f]{2}/i,/[<>'"%;{}()\\]/,/\x00/,/\n|\r|\t|\v|\f/,/[^a-zA-Z0-9-_@/\\:]/],qe=t=>{if(!t)return"";if(t==="/")return"/";const e=N.withoutTrailingSlash(t);return N.withLeadingSlash(e)||"/"},Mt=t=>t.did===vt;class U extends A.Model{static async getProjectByIdOrSlug(e,a){return e?U.findOne({where:{[A.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 _t;const s=e==="/"?"/":N.withoutTrailingSlash(N.withLeadingSlash(e)),n=qe(s);if(s!=="/"&&s.endsWith("/"))return J(i=>`Project slug "${i}" cannot end with /`);if(/\/{2,}/.test(s))return J(i=>`Project slug "${i}" cannot contain consecutive /`);if(/\s/.test(s))return J(i=>`Project slug "${i}" cannot contain whitespace`);if(Ut.some(i=>i.test(s)))return J(i=>`Project slug "${i}" contains invalid characters`);if(E.default.components?.filter(i=>i.mountPoint&&!Mt(i)).some(i=>qe(i.mountPoint)===n))return J(i=>`Project slug "${i}" conflicts with existing blocklet`);const l=await U.findOne({where:{slug:s}});return l&&l?.id!==a?Lt:null}}U.init({id:{type:A.DataTypes.UUID,defaultValue:A.DataTypes.UUIDV4,primaryKey:!0},name:{type:A.DataTypes.STRING,allowNull:!1},description:A.DataTypes.TEXT,createdAt:A.DataTypes.DATE,updatedAt:A.DataTypes.DATE,createdBy:{type:A.DataTypes.STRING,allowNull:!1},updatedBy:{type:A.DataTypes.STRING,allowNull:!1},slug:A.DataTypes.STRING,icon:A.DataTypes.STRING,pinnedAt:A.DataTypes.DATE,useAllResources:A.DataTypes.BOOLEAN,npmSecret:A.DataTypes.STRING,relatedBlocklets:{type:A.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:A.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:A.DataTypes.JSON,allowNull:!0}},{sequelize:B,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:{[A.Op.ne]:null}}}]});U.hasMany(ke,{foreignKey:"projectId",as:"components"});async function q(t){try{return await V.default.promises.access(t,V.default.constants.F_OK),!0}catch{return!1}}function Ge(t,e){return new Promise((a,s)=>{const n=V.default.createReadStream(t),o=V.default.createWriteStream(e);n.on("error",s),o.on("error",s),o.on("finish",a),n.pipe(o)})}async function Ve(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 n=Ne.default.join(t,s.name),o=Ne.default.join(e,s.name);s.isDirectory()?await Ve(n,o):await Ge(n,o)}}async function $t(t,e){(await V.default.promises.stat(t)).isDirectory()?await Ve(t,e):await Ge(t,e)}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 ze(){return Z.mkdtempSync(f.join(E.default.env.dataDir,"tmp-"))}function oe(t,e,a=[]){return Array.isArray(t)?t.flatMap((s,n)=>oe(s,e,[...a,n])):typeof t=="object"?t===null?[]:Object.entries(t).flatMap(([s,n])=>oe(n,e,[...a,s])):e(t)?[a]:[]}function L(t){return t.filter(e=>e!=null)}function Nt(t){t.pages&&Object.keys(t.pages).forEach(a=>{const s=G.getYjsValue(t.pages[a]);s&&s instanceof F.Map&&ne(s)});const e=G.getYjsValue(t.pages);e&&e instanceof F.Map&&e.observe(a=>{a.changes.keys.forEach((s,n)=>{if(s.action==="add"){const o=G.getYjsValue(t.pages[n]);o&&o instanceof F.Map&&ne(o)}})})}function Ft(t){t.routes&&Object.keys(t.routes).forEach(a=>{const s=G.getYjsValue(t.routes?.[a]);s&&s instanceof F.Map&&ne(s)});const e=G.getYjsValue(t.routes);e&&e instanceof F.Map&&e.observe(a=>{a.changes.keys.forEach((s,n)=>{if(s.action==="add"){const o=G.getYjsValue(t.routes?.[n]);o&&o instanceof F.Map&&ne(o)}})})}function qt(t,e){for(const a of e||Object.keys(t.routes||{})){let s=a,n=[];if(a.includes("-")){const[o,...l]=a.split("-");s=o,n=l||[]}if(t.routes?.[s]!==void 0){t.routes[s].publishedAt=new Date().toISOString();const o=t.routes[s];if(!o||!o.params||o.params.length===0)continue;if(a.includes("-")&&n.length>0){const l=ae.getRouteMetaDataByOptionIds(n,o);l&&(l.publishedAt=new Date().toISOString())}if(!e){const l=ae.generateParamCombinations({basePath:o.path,params:o.params,routeId:o.id,paramsOptions:o.paramsOptions,currentIndex:0,currentParams:[],currentOptionIds:[],result:[]});for(const i of l)i.routeMetaData??={},i.routeMetaData.publishedAt=new Date().toISOString()}}}}function me({page:t,route:e,state:a,routeId:s,routePathInfo:n}){u.logger.info(`Executing datasource data assembly, routeId: ${s}, routePathInfo: ${JSON.stringify(n)}`);const o={...Oe.default(t),id:s,slug:n?.path??e.path,createdAt:e.createdAt,updatedAt:n?.routeMetaData?.updatedAt??e.updatedAt,publishedAt:n?.routeMetaData?.publishedAt??e.publishedAt,isPublic:(n?.routeMetaData?.isPublic??e.isPublic)&&e.isPublic};for(const l of a.supportedLocales){if(e.dataSource){let i=e.id;n&&(i=n.paramOptionIds.join("-"));const c=e.dataSource.pathDataMappings?.[i]?.dataCache?.[l.locale]??e.dataSource.pathDataMappings?.[i]?.dataCache?.[a.config.defaultLocale||"en"];if(!c)continue;it.setPageDataSource(o,a,l.locale,c)}n&&n.routeMetaData&&(n.routeMetaData.publishedAt=new Date().toISOString())}return o}["true","1","yes","y"].includes(process.env.USE_FS_CACHE_HTML??"");const Bt=60*60*1e3,W=new je.LRUCache({max:300,ttl:Bt,ttlResolution:10*1e3,allowStale:!0});function xt(t,e=[]){let a=0;const s=Array.from(W.keys()),n=t.map(o=>N.withoutTrailingSlash(o));for(const o of s)for(const l of n){if($e.matchCacheKey(o,{currentPath:l})){W.delete(o),a++,u.logger.info(`[Cache CLEAR] key: ${o}`);break}for(const i of e)if($e.matchCacheKey(o,{currentPath:`/${i}${l}`})){W.delete(o),a++,u.logger.info(`[Cache CLEAR] key: ${o}`);break}}return u.logger.info(`[Cache CLEAR] cleared ${a} entries for paths:`,n),a}function Gt(){const t=W.size;return W.clear(),u.logger.info(`[Cache CLEAR ALL] cleared ${t} entries`),t}E.default.events.on(E.default.Events.envUpdate,Gt);const{uploadToMediaKit:Vt}=require("@blocklet/uploader-server"),_e=/^\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,zt=1e4,Kt=3e4,ee=0,he=1,Yt=0,Ht=1,be=E.default,z=f.join(process.env.BLOCKLET_DATA_DIR,"site-state"),Jt=["production","draft"],Wt=["production"];function re(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 j extends F.Doc{constructor(e){super(),this.options=e,Z.existsSync(this.draftYjsFilePath)&&F.applyUpdate(this,Z.readFileSync(this.draftYjsFilePath)),this.syncedStore=pt.reactive(G.syncedStore({pages:{},pageIds:[],components:{},supportedLocales:[],config:{},resources:{},routeIds:[],routes:{},dataSourceIds:[],dataSources:{}},this)),this.initObserver(),this.on("update",this.updateHandler),this.awareness=new H.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 pageUrlMapCache=new je.LRUCache({max:300,ttl:1e3*60*60*24});static periodicCheckTimer;static async safeDeleteProjectStateDir(e){if(!e)throw new Error("Should provide project context");try{const a=f.join(z,e),s=f.join(z,`@del-${e}`);await O.rename(a,s)}catch(a){u.logger.error("Failed to safe delete project state dir:",a)}}static async getProjectIds(){return(await U.findAll({attributes:["id"],raw:!0}))?.map(e=>e.id)}static get projectIds(){return se.globSync("*/",{cwd:z,ignore:["@del-*","@tmp-*",".*","staging","production","@backup-*","undefined"]})}static get allShared(){return this.projectIds.map(e=>j.shared(e))}static shared(e){if(!e)throw new Error("Should provide project context");let a=j.sharedInstances[e];return a||(a=new j({path:f.join(z,e)}),j.sharedInstances[e]=a,a)}static async getProductionState(e){const a=await U.findByPk(e,{attributes:["productionState"]});if(Te.default(a?.productionState)){const s=f.join(z,e,"production"),n=await Le(s,{includeResources:!0})??Ke();if(!n?.config?.defaultLocale){n.config??={};const o=be.env.languages?.map(l=>({locale:l.code,name:l.name}))||[];n.config.defaultLocale=o[0]?.locale}return n}return a?.productionState}destroy(){this.cancelRelease(),this.save({flush:!0}),this.conns.forEach((a,s)=>this.closeConn(s)),this.awareness.destroy();const e=f.basename(this.options.path);delete j.sharedInstances[e],super.destroy()}initObserver(){Nt(this.syncedStore),Ft(this.syncedStore)}get draftYjsFilePath(){return f.join(this.options.path,"draft.yjs")}static async getStateByProjectId({projectId:e,mode:a,clone:s=!0}){if(a==="draft"){const n=j.shared(e);return s?JSON.parse(JSON.stringify(n.syncedStore)):n.syncedStore}return j.getProductionState(e)}async getState(e){if(e==="draft")return JSON.parse(JSON.stringify(this.syncedStore));const a=f.basename(this.options.path);return j.getProductionState(a)}async setState(e,a){const s=await We(a,{exportAssets:!1,includeResources:!0}),n=this.getPublishDir(e);if(await O.mkdir(f.dirname(n),{recursive:!0}),await O.rm(n,{force:!0,recursive:!0}),await O.rename(s,n),e==="production"){const o=f.basename(this.options.path);j.pageUrlMapCache.delete(o);const l=Oe.default(a);await U.update({productionState:l},{where:{id:o}})}}getPublishDir(e){return f.join(this.options.path,e)}syncedStore;conns=new Map;awareness;releaseTimer;awarenessChangeHandler=({added:e,updated:a,removed:s},n)=>{const o=e.concat(a,s);if(n!==null){const c=this.conns.get(n);c&&(e.forEach(b=>{c.add(b)}),s.forEach(b=>{c.delete(b)}))}const l=k.createEncoder();k.writeVarUint(l,he),k.writeVarUint8Array(l,H.encodeAwarenessUpdate(this.awareness,o));const i=k.toUint8Array(l);this.conns.forEach((c,b)=>this.send(b,i))};updateHandler=e=>{const a=k.createEncoder();k.writeVarUint(a,ee),fe.writeUpdate(a,e);const s=k.toUint8Array(a);this.conns.forEach((n,o)=>this.send(o,s))};ensureDataStructure=()=>{this.transact(()=>{const{supportedLocales:e,pages:a,pageIds:s,config:n,routes:o,routeIds:l}=this.syncedStore;{const i=new Set(Object.keys(a));let c=0;for(;c<s.length;){const b=s[c];i.has(b)?(i.delete(b),c++):s.splice(c,1)}}{const i=new Set(Object.keys(o));let c=0;for(;c<l.length;){const b=l[c];i.has(b)?(i.delete(b),c++):l.splice(c,1)}}e.splice(0,e.length),e.push(...be.env.languages.map(i=>({locale:i.code,name:i.name}))),n.defaultLocale=e[0]?.locale;{let i=0;const c=new Set;for(;i<e.length;){const{locale:b}=e[i];c.has(b)?e.splice(i,1):(i++,c.add(b))}}})};send=(e,a)=>{e.readyState!==Yt&&e.readyState!==Ht&&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&&H.removeAwarenessStates(this.awareness,Array.from(a),null)}e.close(),this.checkAndScheduleRelease()};checkAndScheduleRelease(){this.conns.size===0&&this.scheduleRelease()}scheduleRelease(){this.cancelRelease();const e=f.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())},j.RELEASE_DELAY),u.logger.info(`[SiteState] scheduled release for project ${e} in ${j.RELEASE_DELAY/1e3}s`)}cancelRelease(){if(this.releaseTimer){clearTimeout(this.releaseTimer),this.releaseTimer=void 0;const e=f.basename(this.options.path);u.logger.info(`[SiteState] cancelled scheduled release for project ${e}`)}}autoSave=Ce.default(async()=>{await O.mkdir(f.dirname(this.draftYjsFilePath),{recursive:!0}),await O.writeFile(this.draftYjsFilePath,F.encodeStateAsUpdate(this))},zt);save=({flush:e=!1}={})=>{this.autoSave(),e&&this.autoSave.flush()};publish=async({mode:e,routes:a})=>{const s=f.basename(this.options.path);await nt(s);const n=await this.getState("draft"),o=await this.getState("production");await Pe(n,o,{routes:a,mergeMode:"replace",deleteRoutes:!0,publishMode:e}),o.config.publishedAt=new Date().getTime(),qt(this.syncedStore,a),await this.setState(e,o),await this.clearPageCacheForRoutes(a,o)};mergeState=async(e,a)=>{const s=JSON.parse(JSON.stringify(a));e.config.fontFamily??={};const n=s.config?.fontFamily,o=e.config?.fontFamily;e.config.fontFamily.title=n?.title||o?.title,e.config.fontFamily.description=n?.description||o?.description,await new Promise((l,i)=>{this.transact(async()=>{try{const c=await Pe(e,a);l(c)}catch(c){i(c)}})})};clearPageCacheForRoutes=async(e,a)=>{const s=f.basename(this.options.path),o=(await U.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 i=a.supportedLocales.map(C=>C.locale),c=[],b=l.filter(C=>a.pageIds?.includes(C));for(const C of b){const w=a.pages[C].slug;o&&o!==s&&(o==="/"?c.push(w):c.push(`/${o}${w}`)),c.push(`/${s}${w}`)}if(c.length>0)try{const C=xt(c,i);u.logger.info(`[SiteState] cleared ${C} page cache entries for project ${s}, routes:`,l)}catch{}j.pageUrlMapCache.delete(s)};addConnection=e=>{if(this.conns.has(e))return;this.cancelRelease(),e.binaryType="arraybuffer",this.conns.set(e,new Set),e.on("message",n=>this.messageListener(e,new Uint8Array(n)));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)}}},Kt);e.on("close",()=>{this.closeConn(e),clearInterval(s)}),e.on("pong",()=>{a=!0});{const n=k.createEncoder();k.writeVarUint(n,ee),fe.writeSyncStep1(n,this),this.send(e,k.toUint8Array(n));const o=this.awareness.getStates();if(o.size>0){const l=k.createEncoder();k.writeVarUint(l,he),k.writeVarUint8Array(l,H.encodeAwarenessUpdate(this.awareness,Array.from(o.keys()))),this.send(e,k.toUint8Array(l))}}};messageListener=(e,a)=>{try{const s=k.createEncoder(),n=ge.createDecoder(a),o=ge.readVarUint(n);switch(o){case ee:k.writeVarUint(s,ee),fe.readSyncMessage(n,s,this,null),k.length(s)>1&&(this.ensureDataStructure(),this.send(e,k.toUint8Array(s)));break;case he:{H.applyAwarenessUpdate(this.awareness,ge.readVarUint8Array(n),e);break}default:u.logger.warn(`Unsupported messageType ${o}`)}}catch(s){u.logger.error(s)}this.save()};static async pageUrlMap(e,a){u.logger.info(`[SiteState] get pageUrlMap, mode: ${e}, projectId: ${a}`);let s=[];a?s=[a]:s=await this.getProjectIds();let n={};if(e==="production"&&s?.length){const o=new Map(s?.map(l=>[l,!0])||[]);for(const l of s){const i=j.pageUrlMapCache.get(l);i&&(Object.assign(n,i),o.delete(l))}s=Array.from(o.keys())}if(s?.length){u.logger.info("[SiteState] find project infos from database, projectIds: ",s);const o=30,l=Re.default(5);for(let i=0;i<s.length;i+=o){const c=s.slice(i,i+o);u.logger.info(`[SiteState] processing project batch ${i/o+1}, ids: `,c);const b=await U.findAll({where:{id:{[A.Op.in]:c}},attributes:{exclude:["relatedBlocklets"]}});await Promise.all(b?.map(C=>l(async()=>{const R=C.id,w=C.slug||R,g={},d=e==="production"&&C?.productionState?C.productionState:await j.getStateByProjectId({projectId:C.id,mode:e,clone:!1}),I=jt.default(E.default.env.languages?.map(P=>P.code)||[],d.supportedLocales?.map(P=>P.locale)||[]),D=(P,y)=>{w&&(g[N.joinURL("/",w,P)]={...y,shouldRedirect:!0,mainPage:!0}),g[N.joinURL("/",R,P)]={...y,shouldRedirect:!0,mainPage:!0};for(const v of I){const h={...y,locale:v};g[N.joinURL("/",v,R,P)]=h,w&&(g[N.joinURL("/",v,w,P)]=h)}};if(e==="draft")for(const P of d.routeIds||[]){const y=d?.routes?.[P];if(!y)continue;if(y.params&&y.params.length>0){const S=ae.generateParamCombinations({basePath:y.path,params:y.params,routeId:y.id,paramsOptions:y.paramsOptions,currentIndex:0,currentParams:[],currentOptionIds:[],result:[]});for(const r of S){const p=r.path,m={projectId:R,projectSlug:w,pageSlug:p,pageId:y.displayTemplateId||"",routeId:P,defaultLocale:I?.[0],locales:I,publishedAt:d.config.publishedAt,isPublic:y.isPublic&&r?.routeMetaData?.isPublic};D(p,m)}}const v=y.path,h={projectId:R,projectSlug:w,pageSlug:v,pageId:y.displayTemplateId||"",routeId:P,defaultLocale:I?.[0],locales:I,publishedAt:d.config.publishedAt,isPublic:y.isPublic};D(v,h)}for(const P of d.pageIds||[]){const y=d.pages[P];if(!y||e==="production"&&!y.isPublic)continue;const v=y.slug,h=C.slug||R,S={projectId:R,projectSlug:h,pageSlug:v,pageId:P,defaultLocale:I?.[0],locales:I,publishedAt:d.config.publishedAt,isPublic:y.isPublic,templateConfig:y.templateConfig};D(v,S)}e==="production"&&j.pageUrlMapCache.set(R,g),n={...n,...g}})))}}return u.logger.info("[SiteState] success get pageUrlMap"),n}getDocumentSize(){return F.encodeStateAsUpdate(this).byteLength}static getInstancesSizeInfo(){const e=[];for(const[a,s]of Object.entries(j.sharedInstances)){const n=s.getDocumentSize();e.push({projectId:a,sizeInBytes:n,sizeInMB:`${(n/(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(j.sharedInstances).length,a=[],s=[];for(const[n,o]of Object.entries(j.sharedInstances))o.conns.size===0?a.push({projectId:n,instance:o}):s.push({projectId:n,connections:o.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(o=>o.projectId));let n=0;for(const{projectId:o,instance:l}of a)try{u.logger.info(`[SiteState] releasing instance due to periodic check: ${o}`),l.destroy(),n++}catch(i){u.logger.error(`[SiteState] failed to release instance ${o} during periodic check:`,i)}u.logger.info(`[SiteState] periodic check completed: ${n}/${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 Xt(t,e,a){if(!t||!await q(t)||!(await O.lstat(t)).isFile())return null;let n=a[t];return n||(n=(async()=>{try{return(await Vt({filePath:t,fileName:e}))?.data?.filename}catch(o){return u.logger.error(`Failed to upload asset ${t}:`,o),null}})(),a[t]=n),n}const Ye=async(t,e)=>{const a=f.basename(t),s=await Ae.call({name:ve,path:N.joinURL("/uploads",a),responseType:"stream",method:"GET"});if(s.status>=200&&s.status<400){const n=Z.createWriteStream(e);await bt.pipeline(s.data,n)}else throw new Error(`download asset failed ${s.status}`)},He=async(t,e)=>{await Promise.all(t.map(async a=>{try{await Ye(a,f.join(e,f.basename(a)))}catch(s){u.logger.error(`Failed to export assets: ${a}, ${s}`)}}))};function Je(t){return _e.test(t)?[t]:X.test(t)?(Be.lastIndex=0,Array.from(t.matchAll(Be)).map(a=>a[1]).filter(a=>!!a)):[]}async function te(t,e,a){const{getFilename:s,exportAssets:n}=a,o=f.join(e,s(t));if(await O.mkdir(f.dirname(o),{recursive:!0}),await O.writeFile(o,K.stringify(t)),n){const i=oe(t,c=>typeof c=="string"&&(_e.test(c)||X.test(c))).map(c=>{const b=De.default(t,c);return Je(b)}).flat().filter(Boolean);await He(i,f.dirname(o))}}const Ee=new je.LRUCache({max:100,ttl:1*60*1e3});async function xe(t,e,a){const s=oe(t,i=>typeof i=="string"&&(_e.test(i)||X.test(i))),n=Re.default(2),o=s.map(i=>n(async()=>{try{const c=De.default(t,i),b=Je(c);for(const C of b){const R=f.basename(C),w=a.getFilePath(C,i),g=w?`${w}:${R}`:R,d=Ee.get(g);if(d){X.test(c)||Fe.default(t,i,d);return}const I=await Xt(w,R,e);I&&(X.test(c)||Fe.default(t,i,I),Ee.set(g,I))}}catch(c){u.logger.error(`Failed to process upload for path ${i.join(".")}:`,c.message||c.reason)}})),l=await Promise.allSettled(o);a.onFinish?.(l)}async function We(t,{exportAssets:e,pageIds:a="all",componentIds:s="all",rawConfig:n,includeResources:o=!1,routeIds:l="all"}={}){const i=a==="all"?t.pageIds:a,c=dt.getComponentDependencies({state:t,pageIds:i,componentIds:s==="all"?Object.keys(t.components):s});Object.entries(t.components).forEach(([r,p])=>{p.data?.renderer?.type==="component-template"&&c.push(r)});const b=l==="all"?t.routeIds:l,C=r=>({id:r.id,name:r.name,isTemplateSection:r.isTemplateSection??!1,templateDescription:r.templateDescription,component:r.component,config:r.config,visibility:r.visibility,sections:r?.sectionIds?L(r?.sectionIds?.map(p=>{const m=r.sections?.[p];return m&&C(m)})):void 0}),R=(r,p)=>({id:r.id,createdAt:r.createdAt,updatedAt:r.updatedAt,publishedAt:r.publishedAt,isPublic:r.isPublic??!0,templateConfig:r.templateConfig,meta:r.locales?.[p]??{},sections:L(r.sectionIds.map(m=>{const T=r.sections[m];return T&&C(T)})),dataSource:Object.fromEntries(Object.entries(r.dataSource||{}).map(([m,T])=>[m,T?.[p]??{}]))}),w=r=>({id:r.id,createdAt:r.createdAt,updatedAt:r.updatedAt,publishedAt:r.publishedAt,path:r.path,handler:r.handler,isPublic:r.isPublic??!0,params:r.params??[],enabledGenerate:r.enabledGenerate??!1,displayTemplateId:r.displayTemplateId,dataSource:r.dataSource}),g=L(b.map(r=>{const p=t.routes[r];return p&&w(p)})),d=L(t.supportedLocales.map(r=>r.locale).flatMap(r=>i.map(p=>{const m=t.pages[p];return m&&{locale:r,slug:m.slug,page:R(m,r)}}))),I=ze(),D=f.join(I,"pages");await O.mkdir(D,{recursive:!0});const P=f.join(I,"components");await O.mkdir(P,{recursive:!0});const y=f.join(I,"routes");await O.mkdir(y,{recursive:!0});for(const{locale:r,slug:p,page:m}of d)await te(m,D,{getFilename:()=>`${re(p)||"index"}.${r}.yml`,exportAssets:e});for(const r of g)await te(r,y,{getFilename:()=>`${re(r.path)||"index"}.yml`,exportAssets:e});for(const r of c){const p=t.components[r]?.data;p&&await te(p,P,{getFilename:m=>`${m.name||"unnamed"}.${m.id}.yml`,exportAssets:e})}const v=f.join(I,".blocklet/pages/pages.config.yml");await O.mkdir(f.dirname(v),{recursive:!0});const h={pages:L(i.map(r=>{const p=t.pages[r];return p&&{id:r,slug:p.slug}})),routes:L(b.map(r=>{const p=t.routes[r];return p&&{id:r,path:p.path}})),components:L(c.map(r=>{const p=t.components[r]?.data;return p&&{id:r,name:p.name}})),...o?{resources:{components:L(Object.keys(t.resources?.components||{}).filter(r=>c.includes(r)).map(r=>({id:r,name:t.resources?.components?.[r]?.component?.name})))}}:{},supportedLocales:t.supportedLocales,config:t.config};await O.writeFile(v,K.stringify(h));const S=f.join(I,"config.source.json");if(n&&await O.writeFile(S,JSON.stringify(n)),o){const r=f.join(I,"resources"),p=f.join(r,"components");await O.mkdir(p,{recursive:!0});for(const M of Object.keys(t?.resources?.components??{}).filter(_=>c.includes(_))){const _=t.resources?.components?.[M]?.component;_&&await te(_,p,{getFilename:x=>`${x.name||"unnamed"}.${x.id}.yml`,exportAssets:e})}const m=f.join(I,"chunks");await O.mkdir(m,{recursive:!0});const T=await Qt();for(const M of Object.keys(t?.resources?.components??{}).filter(_=>c.includes(_))){const _=t.resources?.components?.[M]?.component;if(_&&_.renderer?.type==="react-component"){const x=_.renderer?.chunks??[];if(x?.length>0)for(const Y of x){const Ue=f.join(m,Y),pe=T?.[Y];try{pe&&await q(pe)&&!await q(Ue)&&await O.copyFile(pe,Ue)}catch(ot){u.logger.error(`copy chunk ${Y} error`,ot.message)}}}}}return I}async function Le(t,{importAssets:e,includeResources:a}={}){if(!await q(t))return null;let s,n=!1;try{(await O.lstat(t)).isDirectory()?s=t:/\.(tgz|gz|tar)$/.test(t)&&(n=!0,s=ze(),await Et.x({file:t,C:s}));const i=(await se.glob("**/.blocklet/pages/pages.config.yml",{cwd:s,absolute:!0}))[0],c=i&&f.join(f.dirname(i),"../../pages"),b=i&&f.join(f.dirname(i),"../../components"),C=i&&f.join(f.dirname(i),"../../routes");if(!i)return null;const R=await O.readFile(i,"utf-8"),w=K.parse(R),g=async(h,S,r)=>{let p=f.join(h,`${S}${r?`.${r}`:""}.yml`);if(!await q(p)&&(p=f.join(h,S,`index${r?`.${r}`:""}.yml`),!await q(p))||!(await O.lstat(p)).isFile())return null;const T=await O.readFile(p,"utf-8");return K.parse(T)},d=async(h,S)=>{try{const p=(await se.glob(`*.${S}.yml`,{cwd:h,absolute:!0}))[0];if(!p)return null;const m=await O.readFile(p,"utf-8");return K.parse(m)}catch(r){u.logger.error("parse component error",r)}return null},I=async(h,S)=>{let r=f.join(h,`${S}.yml`);if(!await q(r)&&(r=f.join(h,S,"index.yml"),!await q(r))||!(await O.lstat(r)).isFile())return null;const m=await O.readFile(r,"utf-8");return K.parse(m)},D=L(await Promise.all(w.pages.map(async({slug:h})=>{const S=L(await Promise.all(w.supportedLocales.map(async({locale:m})=>{const T=c?await g(c,re(h),m):void 0;if(T)return{locale:m,page:T};const M=c?await g(c,h,m):void 0;return M&&{locale:m,page:M}}))),r=S[0]?.page;if(!r)return null;const p=r.sections.map(ut.unzipSection);return{id:r.id||Me.nextId(),createdAt:r.createdAt,updatedAt:r.updatedAt,publishedAt:r.publishedAt,isPublic:r.isPublic??!0,templateConfig:r.templateConfig,slug:h,sections:Object.fromEntries(p.map(m=>[m.id,m])),sectionIds:p.map(m=>m.id),locales:Object.fromEntries(S.map(({locale:m,page:T})=>[m,T.meta])),dataSource:r.dataSource?Object.fromEntries([...new Set(S.flatMap(({page:m})=>Object.keys(m.dataSource??{})))].map(m=>[m,Object.fromEntries(S.map(({locale:T,page:M})=>{const _=M.dataSource?.[m];return[T,_||{}]}))])):Object.fromEntries([...new Set(S.flatMap(({page:m})=>m.sections.map(T=>T.id)))].map(m=>[m,Object.fromEntries(S.map(({locale:T,page:M})=>{const _=M.dataSource?.[m];if(_)return[T,_];const x=M.sections.find(Y=>Y.id===m);return[T,x?.properties||{}]}))]))}}))),P=L(await Promise.all((w?.routes||[]).map(async({path:h})=>{const S=C?await I(C,re(h)):void 0;return{...S,id:S?.id||Me.nextId(),createdAt:S?.createdAt??new Date().toISOString(),updatedAt:S?.updatedAt??new Date().toISOString(),publishedAt:new Date(0).toISOString(),path:S?.path??`/${S?.id}`,params:S?.params,handler:S?.handler??"Pages Kit",isPublic:S?.isPublic??!0,enabledGenerate:S?.enabledGenerate??!1,displayTemplateId:S?.displayTemplateId??void 0,dataSource:S?.dataSource??{}}}))),y=b?L(await Promise.all((w.components||[]).map(async({id:h})=>d(b,h)))):[];if(e){const h=(...S)=>{u.logger.info(`[${n?f.basename(t):f.basename(f.join(t,"../../../../"))}] importAssets:`,...S)};try{h("wait image-bin api ready"),await Ot.default({resources:[`${Ae.getComponentWebEndpoint(u.IMAGE_BIN_NAME)}/api/sdk/uploads`],validateStatus:p=>p>=200&&p<=500}),h("image-bin api is ready");const S={},r={};h("start to upload assets"),await Promise.allSettled([xe(y,S,{getFilePath:p=>b&&f.join(b,p),onFinish:p=>{h(`upload ${p.length} component assets`)}}),xe(D,r,{getFilePath:(p,m)=>{const T=De.default(D,m.slice(0,1));return c&&f.join(c,f.dirname(T.slug),p)},onFinish:p=>{h(`upload ${p.length} page assets`)}})]),h("upload assets done"),Ee.clear(),global.gc&&global.gc()}catch(S){h("Error during asset import:",S)}}const v={};if(a){const h=i&&f.join(f.dirname(i),"../../resources/components"),S=L(await Promise.all((w.resources?.components||[]).map(async({id:r})=>d(h,r))));S.length>0&&(v.components=Object.fromEntries(S.map((r,p)=>[r.id,{index:p,component:r}])))}return{supportedLocales:w.supportedLocales,pageIds:D.map(h=>h.id),components:Object.fromEntries(y.map((h,S)=>[h.id,{index:S,data:h}])),pages:Object.fromEntries(D.map(h=>[h.id,h])),config:w.config||{},resources:v,routeIds:P.map(h=>h.id),routes:Object.fromEntries(P.map(h=>[h.id,h])),dataSourceIds:[],dataSources:{}}}finally{n&&s&&await O.rm(s,{force:!0,recursive:!0})}}async function Pe(t,e,{routes:a,mergeMode:s="byUpdateTime",deleteRoutes:n=!1,publishMode:o=void 0}={}){try{o&&u.clearPreloadComponentsCacheByMode(o)}catch(w){u.logger.error("clear preload page cache error",{error:w})}const{pages:l,pageIds:i,routeIds:c,routes:b,supportedLocales:C}=t;if(o==="production"){let w=a??[],g=null;for(const d of c??[]){const I=b?.[d];if(I?.params&&I?.params.length>0&&I?.paramsOptions&&I?.paramsOptions.length>0){const D=ae.generateParamCombinations({basePath:I.path,params:I.params,routeId:I.id,paramsOptions:I.paramsOptions,currentIndex:0,currentParams:[],currentOptionIds:[],result:[]}),P=Object.fromEntries(D.map(y=>[`${d}-${y.paramOptionIds.join("-")}`,y]));g={...g||{},...P},a||(w=[...w,...D.map(y=>`${d}-${y.paramOptionIds.join("-")}`)])}else a||w.push(d)}u.logger.info("routeIds to be published: ",w);for(const d of w){let I=d;if(I.includes("-")){const[y]=I.split("-");I=y}const D=b?.[I];if(!D){const y=e.pageIds.indexOf(I);y!==-1&&n&&(e.pageIds.splice(y,1),delete e.pages[I]);for(const v of e.pageIds)v.includes(`${I}-`)&&(e.pageIds.splice(e.pageIds.indexOf(v),1),delete e.pages[v]);u.logger.info("delete main route page",I);continue}if(d.includes("-")&&!g?.[d]){const y=e.pageIds.indexOf(d);y!==-1&&n&&(e.pageIds.splice(y,1),delete e.pages[d]),u.logger.info("delete page",d);continue}if(!D.displayTemplateId){u.logger.info("no display template",d);continue}const P=l[D.displayTemplateId];if(!P){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:P,route:D,state:t,routeId:d,routePathInfo:g?.[d]}),u.logger.info("replace page",d);else if(s==="byUpdateTime"){const y=e.pages[D.id];(!y||D.updatedAt&&D.updatedAt>y.updatedAt)&&(e.pages[d]=me({page:P,route:D,state:t,routeId:d,routePathInfo:g?.[d]}),u.logger.info("replace page by update time",d))}}else e.pageIds.push(d),e.pages[d]=me({page:P,route:D,state:t,routeId:d,routePathInfo:g?.[d]}),u.logger.info("add page",d)}if(n&&!a)for(const d of e.pageIds)w?.includes(d)||(delete e.pages[d],u.logger.info("delete page",d)),e.pageIds=[...e.pageIds].filter(I=>w?.includes(I))}else{for(const w of i){const g=l[w];if(g)if(e.pageIds.includes(g.id)){if(s==="replace")e.pages[g.id]=g;else if(s==="byUpdateTime"){const d=e.pages[g.id];(!d||g.updatedAt&&g.updatedAt>d.updatedAt)&&(e.pages[g.id]=g)}}else e.pageIds.push(g.id),e.pages[g.id]=g}for(const w of c){const g=b[w];if(g)if(e.routeIds.includes(g.id)){if(s==="replace")e.routes[g.id]=g;else if(s==="byUpdateTime"){const d=e.routes[g.id];(!d||g.updatedAt&&g.updatedAt>d.updatedAt)&&(e.routes[g.id]=g)}}else e.routeIds.push(g.id),e.routes[g.id]=g}}if(e.supportedLocales.splice(0,e.supportedLocales.length),e.supportedLocales.push(...Oe.default(C)),n)for(const w of Object.keys(e.components))delete e.components[w];let R=JSON.parse(JSON.stringify(t.components));R=Object.fromEntries(await Promise.all(Object.entries(R).map(async([w,g])=>{const d=await Xe(g?.data);return[w,{...g,data:d}]}))),Object.assign(e.components,R),Object.assign(e.config,JSON.parse(JSON.stringify(t.config))),Te.default(t.resources.components)||(e.resources.components=JSON.parse(JSON.stringify(t.resources.components||{})))}const Xe=u.memoizeWithFs(async t=>{if(!Te.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((n,o)=>{t?.properties&&(t.properties[n.id]={index:o,data:n})}))}catch(s){u.logger.error("getPropertiesFromCode error",{componentId:t.id,name:t.name},{error:s})}}return t},{subdir:"getPropertiesFromCode"});let ie,Q,le,ue;const Qe=()=>Ae.getResources({types:[{did:ve,type:we},{did:Rt,type:we}]}),Qt=async()=>{const t=Qe(),e={};for(const a of t){const n=(await se.glob("**/.blocklet/pages/pages.config.yml",{cwd:a.path,absolute:!0}))[0],o=n&&f.join(f.dirname(n),"../../chunks");if(o&&await q(o)){const l=await O.readdir(o);for(const i of l)e[i]=f.join(o,i)}}return e};function Ze(){return ie=(async()=>{const t=Qe();Q=(await Promise.all(t.map(async a=>{const s=a.path?await Le(a.path,{importAssets:!1}):void 0;return s?{blockletId:a.did,state:s,blockletTitle:a.title}:void 0}))).filter(a=>!!a),le=Q.reduce((a,s)=>Object.assign(a,Object.fromEntries(Object.values(s.state.pages).map(n=>n?[n?.id,{page:n,blockletId:s.blockletId}]:[]))),{});const e=Q.reduce((a,s)=>Object.assign(a,Object.fromEntries(Object.values(s.state.components).map(n=>[n.data.id,{blockletId:s.blockletId,component:n.data}]))),{});ue=Object.fromEntries(await Promise.all(Object.entries(e).map(async([a,s])=>{const n=await Xe(s.component);return[a,{...s,component:n}]})))})(),ie}function et(t){const e=Ce.default(async()=>{await Ze().catch(a=>{u.logger.error("load resource states error",{error:a})}),await t?.({states:Q,pages:le,components:ue})},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 tt=Symbol.for("GLOBAL_RESOURCE_STATES_LISTENER_KEY"),at=Symbol.for("GLOBAL_ENV_UPDATE_LISTENER_KEY"),de=globalThis;de[tt]?.();de[tt]=et(async({pages:t,components:e})=>{const a=await j.getProjectIds();u.logger.info(`start update resource states projects(${a.length})`,a);const s=Re.default(10);await Promise.race([new Promise(n=>{setTimeout(()=>{n({})},30*1e3)}),Promise.all(a.map(n=>s(async()=>{st({projectId:n,pages:t,components:e})})))]).catch(n=>{u.logger.error("update resource states failed:",n)})});de[at]?.();de[at]=()=>{const t=()=>{j.pageUrlMapCache.clear(),u.logger.info("[Cache CLEAR ALL] clear all page url map cache by env update")};return E.default.events.on(E.default.Events.envUpdate,t),()=>{E.default.events.off(E.default.Events.envUpdate,t)}};j.startPeriodicCheck();process.on("beforeExit",()=>{j.stopPeriodicCheck()});process.on("SIGINT",()=>{j.stopPeriodicCheck(),process.exit(0)});process.on("SIGTERM",()=>{j.stopPeriodicCheck(),process.exit(0)});async function st({projectId:t,pages:e,components:a}){const s=j.sharedInstances[t];if(!s){u.logger.info(`projectId: ${t} not found in sharedInstances`);return}s.transact(async()=>{if(s.syncedStore.resources.pages=e,(await U.findByPk(t))?.useAllResources)s.syncedStore.resources.components=a;else{const l=(await ke.findAll({where:{projectId:t}})).map(c=>c.componentId),i=Object.fromEntries(Object.entries(a||{}).filter(([c])=>l.includes(c)));s.syncedStore.resources.components=i}}),u.logger.info(`update [${t}] resource states:`,{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=Ce.default(async a=>st({projectId:a,pages:le,components:ue}),3e3);ye.set(t,e)}return ye.get(t)(t)}async function Zt(){u.logger.info("trigger reload all project resource"),E.default.events.emit(Ie)}async function ea({ensureLoaded:t=!0}={}){return t&&(ie??=Ze(),await ie),{states:Q,pages:le,components:ue}}exports.COMPONENT_DID=ve;exports.PUBLISH_MODES=Wt;exports.Project=U;exports.RESOURCE_TYPE=we;exports.SITE_STATE_PATH=z;exports.STATE_MODES=Jt;exports.SiteState=j;exports.copyRecursive=$t;exports.downloadAsset=Ye;exports.downloadAssets=He;exports.fromPackage=Le;exports.getDefaultState=Ke;exports.getResourceStates=ea;exports.initPackResourceStates=et;exports.mergeState=Pe;exports.toPackage=We;exports.triggerReloadAllProjectResource=Zt;exports.updateResourceStatesByProjectId=nt;
|
package/lib/cjs/resources.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const f=require("./chunks/components-CnPdZJ2Z.js"),c=require("./chunks/site-state-
|
|
1
|
+
"use strict";const f=require("./chunks/components-CnPdZJ2Z.js"),c=require("./chunks/site-state-D5CfLsg2.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);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"})}},O=(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(),A="@page",B="@component",m=":",R="ALL",b="@project",v=({pageId:e,projectId:t})=>[A,t,e].join(m),K=e=>{const[t,o,s]=e.split(m);if(t===A)return{pageId:s,projectId:o}},D=({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=>[b,e].join(m),$=e=>{const[t,o]=e.split(m);if(t===b)return o},z=e=>{try{return JSON.parse(e)}catch{}return{}};async function x(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:D({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:D({componentId:R,projectId:e}),name:"Components",children:n}]}}y.get("/resources",O,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 x(o);t.json({resources:[r]});return}const s=await c.Project.findAll({where:{}}),n=await Promise.all(s.map(r=>x(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",O,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"),S=k.default(I,"projectId"),N=new Set([...Object.keys(g),...Object.keys(S)]),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=S[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",O,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-CnPdZJ2Z.js");const e=require("./chunks/site-state-
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});require("./chunks/components-CnPdZJ2Z.js");const e=require("./chunks/site-state-D5CfLsg2.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]})});
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { d as ze, l as d, I as it, c as ct, m as lt, b as pt } from "./components-CcZk17uO.js";
|
|
2
2
|
import { getYjsValue as K, syncedStore as ut } from "@syncedstore/core";
|
|
3
|
-
import * as
|
|
3
|
+
import * as _ from "yjs";
|
|
4
4
|
import { setPageDataSource as dt } from "@blocklet/pages-kit/utils/data-source";
|
|
5
|
-
import { getRouteMetaDataByOptionIds as ft, generateParamCombinations as
|
|
6
|
-
import
|
|
5
|
+
import { getRouteMetaDataByOptionIds as ft, generateParamCombinations as Ee } from "@blocklet/pages-kit/utils/route";
|
|
6
|
+
import be from "lodash/cloneDeep";
|
|
7
7
|
import E from "@blocklet/sdk/lib/config";
|
|
8
8
|
import V, { mkdtempSync as mt, existsSync as gt, readFileSync as ht, createWriteStream as yt } from "fs";
|
|
9
9
|
import Le, { join as b, basename as U, dirname as M } from "path";
|
|
@@ -12,9 +12,9 @@ import { unzipSection as St } from "@blocklet/pages-kit/utils/page-model";
|
|
|
12
12
|
import { getComponentDependencies as wt } from "@blocklet/pages-kit/utils/property";
|
|
13
13
|
import { getComponentWebEndpoint as It, getResources as Et, call as bt } from "@blocklet/sdk/lib/component";
|
|
14
14
|
import { reactive as Pt } from "@reactivedata/reactive";
|
|
15
|
-
import { rename as $e, mkdir as F, rm as Ke, writeFile as
|
|
16
|
-
import { globSync as Ot, glob as
|
|
17
|
-
import * as
|
|
15
|
+
import { rename as $e, mkdir as F, rm as Ke, writeFile as ae, copyFile as At, lstat as se, readFile as Z, readdir as Ct } from "fs/promises";
|
|
16
|
+
import { globSync as Ot, glob as he } from "glob";
|
|
17
|
+
import * as de from "lib0/decoding";
|
|
18
18
|
import * as T from "lib0/encoding";
|
|
19
19
|
import Pe from "lodash/debounce";
|
|
20
20
|
import Ae from "lodash/get";
|
|
@@ -28,14 +28,14 @@ import { pipeline as Rt } from "stream/promises";
|
|
|
28
28
|
import { x as Dt } from "tar";
|
|
29
29
|
import { withoutTrailingSlash as Re, withLeadingSlash as He, joinURL as Y } from "ufo";
|
|
30
30
|
import Tt from "wait-on";
|
|
31
|
-
import { Awareness as kt, encodeAwarenessUpdate as
|
|
32
|
-
import { writeUpdate as $t, writeSyncStep1 as Mt, readSyncMessage as
|
|
31
|
+
import { Awareness as kt, encodeAwarenessUpdate as Ne, removeAwarenessStates as Lt, applyAwarenessUpdate as Ut } from "y-protocols/awareness";
|
|
32
|
+
import { writeUpdate as $t, writeSyncStep1 as Mt, readSyncMessage as Nt } from "y-protocols/sync";
|
|
33
33
|
import * as z from "yaml";
|
|
34
|
-
import { m as
|
|
34
|
+
import { m as _e } from "./html-CNFwwbdj.js";
|
|
35
35
|
import "sqlite3";
|
|
36
36
|
import "@blocklet/pages-kit/types/state";
|
|
37
|
-
const
|
|
38
|
-
j.sqlite.DATE.parse = (t, e) => typeof t == "number" ? new Date(t) :
|
|
37
|
+
const _t = j.sqlite.DATE.parse;
|
|
38
|
+
j.sqlite.DATE.parse = (t, e) => typeof t == "number" ? new Date(t) : _t(t, e);
|
|
39
39
|
const B = new jt({
|
|
40
40
|
dialect: "sqlite",
|
|
41
41
|
storage: ze,
|
|
@@ -73,16 +73,16 @@ async function Ft(t, e) {
|
|
|
73
73
|
console.error("Failed to cleanup SQLite memory", e, s);
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
|
-
let
|
|
77
|
-
|
|
78
|
-
|
|
76
|
+
let ye = null;
|
|
77
|
+
ye && clearInterval(ye);
|
|
78
|
+
ye = setInterval(
|
|
79
79
|
async () => {
|
|
80
80
|
d.info("Start cleanupSqliteMemory"), await Ft(B, ze), d.info("End cleanupSqliteMemory");
|
|
81
81
|
},
|
|
82
82
|
60 * 1e3 * 10
|
|
83
83
|
// 10 minutes
|
|
84
84
|
);
|
|
85
|
-
const xt = "z8iZiDFg3vkkrPwsiba1TLXy3H9XHzFERsP8o", Fe = "page",
|
|
85
|
+
const xt = "z8iZiDFg3vkkrPwsiba1TLXy3H9XHzFERsP8o", Fe = "page", Se = "trigger-reload-project-resource", Je = xt, Bt = "z2qa7BQdkEb3TwYyEYC1psK6uvmGnHSUHt5RM", Gt = "z8iZiDFg3vkkrPwsiba1TLXy3H9XHzFERsP8o";
|
|
86
86
|
class De extends qe {
|
|
87
87
|
// Foreign key to Component
|
|
88
88
|
}
|
|
@@ -142,9 +142,9 @@ const Vt = "SLUG_INVALID", H = (t) => ({
|
|
|
142
142
|
const e = Re(t);
|
|
143
143
|
return He(e) || "/";
|
|
144
144
|
}, Ht = (t) => t.did === Gt;
|
|
145
|
-
class
|
|
145
|
+
class N extends qe {
|
|
146
146
|
static async getProjectByIdOrSlug(e, s) {
|
|
147
|
-
return e ?
|
|
147
|
+
return e ? N.findOne({
|
|
148
148
|
where: {
|
|
149
149
|
[je.or]: [{ id: e }, { slug: e }],
|
|
150
150
|
...s?.createdBy ? { createdBy: s.createdBy } : {}
|
|
@@ -170,13 +170,13 @@ class _ extends qe {
|
|
|
170
170
|
return H((i) => `Project slug "${i}" contains invalid characters`);
|
|
171
171
|
if (E.components?.filter((i) => i.mountPoint && !Ht(i)).some((i) => xe(i.mountPoint) === o))
|
|
172
172
|
return H((i) => `Project slug "${i}" conflicts with existing blocklet`);
|
|
173
|
-
const l = await
|
|
173
|
+
const l = await N.findOne({
|
|
174
174
|
where: { slug: a }
|
|
175
175
|
});
|
|
176
176
|
return l && l?.id !== s ? Kt : null;
|
|
177
177
|
}
|
|
178
178
|
}
|
|
179
|
-
|
|
179
|
+
N.init(
|
|
180
180
|
{
|
|
181
181
|
id: {
|
|
182
182
|
type: j.UUID,
|
|
@@ -280,7 +280,7 @@ _.init(
|
|
|
280
280
|
]
|
|
281
281
|
}
|
|
282
282
|
);
|
|
283
|
-
|
|
283
|
+
N.hasMany(De, {
|
|
284
284
|
foreignKey: "projectId",
|
|
285
285
|
as: "components"
|
|
286
286
|
});
|
|
@@ -308,7 +308,7 @@ async function We(t, e) {
|
|
|
308
308
|
async function Ks(t, e) {
|
|
309
309
|
(await V.promises.stat(t)).isDirectory() ? await We(t, e) : await Ye(t, e);
|
|
310
310
|
}
|
|
311
|
-
function
|
|
311
|
+
function oe(t) {
|
|
312
312
|
t.observeDeep((e) => {
|
|
313
313
|
e.some((s) => s.changes.keys.has("updatedAt") || s.changes.keys.has("publishedAt")) || t.set("updatedAt", (/* @__PURE__ */ new Date()).toISOString());
|
|
314
314
|
});
|
|
@@ -316,8 +316,8 @@ function ne(t) {
|
|
|
316
316
|
function Xe() {
|
|
317
317
|
return mt(b(E.env.dataDir, "tmp-"));
|
|
318
318
|
}
|
|
319
|
-
function
|
|
320
|
-
return Array.isArray(t) ? t.flatMap((a, o) =>
|
|
319
|
+
function ne(t, e, s = []) {
|
|
320
|
+
return Array.isArray(t) ? t.flatMap((a, o) => ne(a, e, [...s, o])) : typeof t == "object" ? t === null ? [] : Object.entries(t).flatMap(([a, o]) => ne(o, e, [...s, a])) : e(t) ? [s] : [];
|
|
321
321
|
}
|
|
322
322
|
function L(t) {
|
|
323
323
|
return t.filter((e) => e != null);
|
|
@@ -325,14 +325,14 @@ function L(t) {
|
|
|
325
325
|
function Jt(t) {
|
|
326
326
|
t.pages && Object.keys(t.pages).forEach((s) => {
|
|
327
327
|
const a = K(t.pages[s]);
|
|
328
|
-
a && a instanceof
|
|
328
|
+
a && a instanceof _.Map && oe(a);
|
|
329
329
|
});
|
|
330
330
|
const e = K(t.pages);
|
|
331
|
-
e && e instanceof
|
|
331
|
+
e && e instanceof _.Map && e.observe((s) => {
|
|
332
332
|
s.changes.keys.forEach((a, o) => {
|
|
333
333
|
if (a.action === "add") {
|
|
334
334
|
const n = K(t.pages[o]);
|
|
335
|
-
n && n instanceof
|
|
335
|
+
n && n instanceof _.Map && oe(n);
|
|
336
336
|
}
|
|
337
337
|
});
|
|
338
338
|
});
|
|
@@ -340,14 +340,14 @@ function Jt(t) {
|
|
|
340
340
|
function Yt(t) {
|
|
341
341
|
t.routes && Object.keys(t.routes).forEach((s) => {
|
|
342
342
|
const a = K(t.routes?.[s]);
|
|
343
|
-
a && a instanceof
|
|
343
|
+
a && a instanceof _.Map && oe(a);
|
|
344
344
|
});
|
|
345
345
|
const e = K(t.routes);
|
|
346
|
-
e && e instanceof
|
|
346
|
+
e && e instanceof _.Map && e.observe((s) => {
|
|
347
347
|
s.changes.keys.forEach((a, o) => {
|
|
348
348
|
if (a.action === "add") {
|
|
349
349
|
const n = K(t.routes?.[o]);
|
|
350
|
-
n && n instanceof
|
|
350
|
+
n && n instanceof _.Map && oe(n);
|
|
351
351
|
}
|
|
352
352
|
});
|
|
353
353
|
});
|
|
@@ -369,7 +369,7 @@ function Wt(t, e) {
|
|
|
369
369
|
l && (l.publishedAt = (/* @__PURE__ */ new Date()).toISOString());
|
|
370
370
|
}
|
|
371
371
|
if (!e) {
|
|
372
|
-
const l =
|
|
372
|
+
const l = Ee({
|
|
373
373
|
basePath: n.path,
|
|
374
374
|
params: n.params,
|
|
375
375
|
routeId: n.id,
|
|
@@ -385,7 +385,7 @@ function Wt(t, e) {
|
|
|
385
385
|
}
|
|
386
386
|
}
|
|
387
387
|
}
|
|
388
|
-
function
|
|
388
|
+
function fe({
|
|
389
389
|
page: t,
|
|
390
390
|
route: e,
|
|
391
391
|
state: s,
|
|
@@ -396,7 +396,7 @@ function me({
|
|
|
396
396
|
`Executing datasource data assembly, routeId: ${a}, routePathInfo: ${JSON.stringify(o)}`
|
|
397
397
|
);
|
|
398
398
|
const n = {
|
|
399
|
-
...
|
|
399
|
+
...be(t),
|
|
400
400
|
id: a,
|
|
401
401
|
slug: o?.path ?? e.path,
|
|
402
402
|
createdAt: e.createdAt,
|
|
@@ -418,7 +418,7 @@ function me({
|
|
|
418
418
|
return n;
|
|
419
419
|
}
|
|
420
420
|
["true", "1", "yes", "y"].includes(process.env.USE_FS_CACHE_HTML ?? "");
|
|
421
|
-
const Xt = 60 * 60 * 1e3,
|
|
421
|
+
const Xt = 60 * 60 * 1e3, W = new Oe({
|
|
422
422
|
max: 300,
|
|
423
423
|
ttl: Xt,
|
|
424
424
|
ttlResolution: 10 * 1e3,
|
|
@@ -427,32 +427,32 @@ const Xt = 60 * 60 * 1e3, X = new Oe({
|
|
|
427
427
|
});
|
|
428
428
|
function Qt(t, e = []) {
|
|
429
429
|
let s = 0;
|
|
430
|
-
const a = Array.from(
|
|
430
|
+
const a = Array.from(W.keys()), o = t.map((n) => Re(n));
|
|
431
431
|
for (const n of a)
|
|
432
432
|
for (const l of o) {
|
|
433
|
-
if (
|
|
434
|
-
|
|
433
|
+
if (_e(n, { currentPath: l })) {
|
|
434
|
+
W.delete(n), s++, d.info(`[Cache CLEAR] key: ${n}`);
|
|
435
435
|
break;
|
|
436
436
|
}
|
|
437
437
|
for (const i of e)
|
|
438
|
-
if (
|
|
439
|
-
|
|
438
|
+
if (_e(n, { currentPath: `/${i}${l}` })) {
|
|
439
|
+
W.delete(n), s++, d.info(`[Cache CLEAR] key: ${n}`);
|
|
440
440
|
break;
|
|
441
441
|
}
|
|
442
442
|
}
|
|
443
443
|
return d.info(`[Cache CLEAR] cleared ${s} entries for paths:`, o), s;
|
|
444
444
|
}
|
|
445
445
|
function Zt() {
|
|
446
|
-
const t =
|
|
447
|
-
return
|
|
446
|
+
const t = W.size;
|
|
447
|
+
return W.clear(), d.info(`[Cache CLEAR ALL] cleared ${t} entries`), t;
|
|
448
448
|
}
|
|
449
449
|
E.events.on(E.Events.envUpdate, Zt);
|
|
450
|
-
const { uploadToMediaKit: es } = require("@blocklet/uploader-server"), Te = /^\w+(\w|-|\.)+\w+\.(jpe?g|png|gif|svg|bmp|webp|mp4|m4v|webm)$/,
|
|
451
|
-
function
|
|
450
|
+
const { uploadToMediaKit: es } = require("@blocklet/uploader-server"), Te = /^\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, ts = 1e4, ss = 3e4, ee = 0, me = 1, as = 0, os = 1, we = E, J = b(process.env.BLOCKLET_DATA_DIR, "site-state"), qs = ["production", "draft"], Hs = ["production"];
|
|
451
|
+
function re(t) {
|
|
452
452
|
return t?.replace(/\//g, "|") || "";
|
|
453
453
|
}
|
|
454
454
|
function ns() {
|
|
455
|
-
const t =
|
|
455
|
+
const t = we.env.languages?.map((s) => ({ locale: s.code, name: s.name })) || [], e = t[0]?.locale || "en";
|
|
456
456
|
return {
|
|
457
457
|
pageIds: [],
|
|
458
458
|
pages: {},
|
|
@@ -466,9 +466,9 @@ function ns() {
|
|
|
466
466
|
resources: {}
|
|
467
467
|
};
|
|
468
468
|
}
|
|
469
|
-
class C extends
|
|
469
|
+
class C extends _.Doc {
|
|
470
470
|
constructor(e) {
|
|
471
|
-
super(), this.options = e, gt(this.draftYjsFilePath) &&
|
|
471
|
+
super(), this.options = e, gt(this.draftYjsFilePath) && _.applyUpdate(this, ht(this.draftYjsFilePath)), this.syncedStore = Pt(
|
|
472
472
|
ut(
|
|
473
473
|
{
|
|
474
474
|
pages: {},
|
|
@@ -511,7 +511,7 @@ class C extends N.Doc {
|
|
|
511
511
|
}
|
|
512
512
|
}
|
|
513
513
|
static async getProjectIds() {
|
|
514
|
-
return (await
|
|
514
|
+
return (await N.findAll({ attributes: ["id"], raw: !0 }))?.map((e) => e.id);
|
|
515
515
|
}
|
|
516
516
|
/** @deprecated 不再使用这个 getter 了,仅作为兼容性处理,请使用 getProjectIds 代替 */
|
|
517
517
|
static get projectIds() {
|
|
@@ -535,14 +535,14 @@ class C extends N.Doc {
|
|
|
535
535
|
}
|
|
536
536
|
// 轻量级 production 状态获取,不加载 draft 数据
|
|
537
537
|
static async getProductionState(e) {
|
|
538
|
-
const s = await
|
|
538
|
+
const s = await N.findByPk(e, {
|
|
539
539
|
attributes: ["productionState"]
|
|
540
540
|
});
|
|
541
541
|
if (Ce(s?.productionState)) {
|
|
542
542
|
const a = b(J, e, "production"), o = await Ze(a, { includeResources: !0 }) ?? ns();
|
|
543
543
|
if (!o?.config?.defaultLocale) {
|
|
544
544
|
o.config ??= {};
|
|
545
|
-
const n =
|
|
545
|
+
const n = we.env.languages?.map((l) => ({ locale: l.code, name: l.name })) || [];
|
|
546
546
|
o.config.defaultLocale = n[0]?.locale;
|
|
547
547
|
}
|
|
548
548
|
return o;
|
|
@@ -567,13 +567,13 @@ class C extends N.Doc {
|
|
|
567
567
|
}) {
|
|
568
568
|
if (s === "draft") {
|
|
569
569
|
const o = C.shared(e);
|
|
570
|
-
return a ?
|
|
570
|
+
return a ? JSON.parse(JSON.stringify(o.syncedStore)) : o.syncedStore;
|
|
571
571
|
}
|
|
572
572
|
return C.getProductionState(e);
|
|
573
573
|
}
|
|
574
574
|
async getState(e) {
|
|
575
575
|
if (e === "draft")
|
|
576
|
-
return
|
|
576
|
+
return JSON.parse(JSON.stringify(this.syncedStore));
|
|
577
577
|
const s = U(this.options.path);
|
|
578
578
|
return C.getProductionState(s);
|
|
579
579
|
}
|
|
@@ -582,8 +582,8 @@ class C extends N.Doc {
|
|
|
582
582
|
if (await F(M(o), { recursive: !0 }), await Ke(o, { force: !0, recursive: !0 }), await $e(a, o), e === "production") {
|
|
583
583
|
const n = U(this.options.path);
|
|
584
584
|
C.pageUrlMapCache.delete(n);
|
|
585
|
-
const l =
|
|
586
|
-
await
|
|
585
|
+
const l = be(s);
|
|
586
|
+
await N.update({ productionState: l }, { where: { id: n } });
|
|
587
587
|
}
|
|
588
588
|
}
|
|
589
589
|
getPublishDir(e) {
|
|
@@ -605,13 +605,13 @@ class C extends N.Doc {
|
|
|
605
605
|
}));
|
|
606
606
|
}
|
|
607
607
|
const l = T.createEncoder();
|
|
608
|
-
T.writeVarUint(l,
|
|
608
|
+
T.writeVarUint(l, me), T.writeVarUint8Array(l, Ne(this.awareness, n));
|
|
609
609
|
const i = T.toUint8Array(l);
|
|
610
610
|
this.conns.forEach((c, I) => this.send(I, i));
|
|
611
611
|
};
|
|
612
612
|
updateHandler = (e) => {
|
|
613
613
|
const s = T.createEncoder();
|
|
614
|
-
T.writeVarUint(s,
|
|
614
|
+
T.writeVarUint(s, ee), $t(s, e);
|
|
615
615
|
const a = T.toUint8Array(s);
|
|
616
616
|
this.conns.forEach((o, n) => this.send(n, a));
|
|
617
617
|
};
|
|
@@ -634,7 +634,7 @@ class C extends N.Doc {
|
|
|
634
634
|
i.has(I) ? (i.delete(I), c++) : l.splice(c, 1);
|
|
635
635
|
}
|
|
636
636
|
}
|
|
637
|
-
e.splice(0, e.length), e.push(...
|
|
637
|
+
e.splice(0, e.length), e.push(...we.env.languages.map((i) => ({ locale: i.code, name: i.name }))), o.defaultLocale = e[0]?.locale;
|
|
638
638
|
{
|
|
639
639
|
let i = 0;
|
|
640
640
|
const c = /* @__PURE__ */ new Set();
|
|
@@ -683,7 +683,7 @@ class C extends N.Doc {
|
|
|
683
683
|
}
|
|
684
684
|
}
|
|
685
685
|
autoSave = Pe(async () => {
|
|
686
|
-
await F(M(this.draftYjsFilePath), { recursive: !0 }), await
|
|
686
|
+
await F(M(this.draftYjsFilePath), { recursive: !0 }), await ae(this.draftYjsFilePath, _.encodeStateAsUpdate(this));
|
|
687
687
|
}, ts);
|
|
688
688
|
save = ({ flush: e = !1 } = {}) => {
|
|
689
689
|
this.autoSave(), e && this.autoSave.flush();
|
|
@@ -710,7 +710,7 @@ class C extends N.Doc {
|
|
|
710
710
|
});
|
|
711
711
|
};
|
|
712
712
|
clearPageCacheForRoutes = async (e, s) => {
|
|
713
|
-
const a = U(this.options.path), n = (await
|
|
713
|
+
const a = U(this.options.path), n = (await N.findByPk(a))?.slug || a;
|
|
714
714
|
let l = e;
|
|
715
715
|
(!l || l.length === 0) && (l = s.pageIds ?? []), d.info(`[SiteState] clearing page cache for project ${a}, routes:`, l || []);
|
|
716
716
|
const i = s.supportedLocales.map((A) => A.locale), c = [], I = l.filter((A) => s.pageIds?.includes(A));
|
|
@@ -750,23 +750,23 @@ class C extends N.Doc {
|
|
|
750
750
|
});
|
|
751
751
|
{
|
|
752
752
|
const o = T.createEncoder();
|
|
753
|
-
T.writeVarUint(o,
|
|
753
|
+
T.writeVarUint(o, ee), Mt(o, this), this.send(e, T.toUint8Array(o));
|
|
754
754
|
const n = this.awareness.getStates();
|
|
755
755
|
if (n.size > 0) {
|
|
756
756
|
const l = T.createEncoder();
|
|
757
|
-
T.writeVarUint(l,
|
|
757
|
+
T.writeVarUint(l, me), T.writeVarUint8Array(l, Ne(this.awareness, Array.from(n.keys()))), this.send(e, T.toUint8Array(l));
|
|
758
758
|
}
|
|
759
759
|
}
|
|
760
760
|
};
|
|
761
761
|
messageListener = (e, s) => {
|
|
762
762
|
try {
|
|
763
|
-
const a = T.createEncoder(), o =
|
|
763
|
+
const a = T.createEncoder(), o = de.createDecoder(s), n = de.readVarUint(o);
|
|
764
764
|
switch (n) {
|
|
765
|
-
case
|
|
766
|
-
T.writeVarUint(a,
|
|
765
|
+
case ee:
|
|
766
|
+
T.writeVarUint(a, ee), Nt(o, a, this, null), T.length(a) > 1 && (this.ensureDataStructure(), this.send(e, T.toUint8Array(a)));
|
|
767
767
|
break;
|
|
768
|
-
case
|
|
769
|
-
Ut(this.awareness,
|
|
768
|
+
case me: {
|
|
769
|
+
Ut(this.awareness, de.readVarUint8Array(o), e);
|
|
770
770
|
break;
|
|
771
771
|
}
|
|
772
772
|
default:
|
|
@@ -797,7 +797,7 @@ class C extends N.Doc {
|
|
|
797
797
|
for (let i = 0; i < a.length; i += n) {
|
|
798
798
|
const c = a.slice(i, i + n);
|
|
799
799
|
d.info(`[SiteState] processing project batch ${i / n + 1}, ids: `, c);
|
|
800
|
-
const I = await
|
|
800
|
+
const I = await N.findAll({
|
|
801
801
|
where: {
|
|
802
802
|
id: {
|
|
803
803
|
[je.in]: c
|
|
@@ -833,7 +833,7 @@ class C extends N.Doc {
|
|
|
833
833
|
const h = p?.routes?.[P];
|
|
834
834
|
if (!h) continue;
|
|
835
835
|
if (h.params && h.params.length > 0) {
|
|
836
|
-
const y =
|
|
836
|
+
const y = Ee({
|
|
837
837
|
basePath: h.path,
|
|
838
838
|
params: h.params,
|
|
839
839
|
routeId: h.id,
|
|
@@ -900,7 +900,7 @@ class C extends N.Doc {
|
|
|
900
900
|
return d.info("[SiteState] success get pageUrlMap"), o;
|
|
901
901
|
}
|
|
902
902
|
getDocumentSize() {
|
|
903
|
-
return
|
|
903
|
+
return _.encodeStateAsUpdate(this).byteLength;
|
|
904
904
|
}
|
|
905
905
|
static getInstancesSizeInfo() {
|
|
906
906
|
const e = [];
|
|
@@ -953,7 +953,7 @@ class C extends N.Doc {
|
|
|
953
953
|
}
|
|
954
954
|
}
|
|
955
955
|
async function rs(t, e, s) {
|
|
956
|
-
if (!t || !await x(t) || !(await
|
|
956
|
+
if (!t || !await x(t) || !(await se(t)).isFile())
|
|
957
957
|
return null;
|
|
958
958
|
let o = s[t];
|
|
959
959
|
return o || (o = (async () => {
|
|
@@ -991,14 +991,14 @@ const is = async (t, e) => {
|
|
|
991
991
|
);
|
|
992
992
|
};
|
|
993
993
|
function Qe(t) {
|
|
994
|
-
return Te.test(t) ? [t] :
|
|
994
|
+
return Te.test(t) ? [t] : X.test(t) ? (Be.lastIndex = 0, Array.from(t.matchAll(Be)).map((s) => s[1]).filter((s) => !!s)) : [];
|
|
995
995
|
}
|
|
996
|
-
async function
|
|
996
|
+
async function te(t, e, s) {
|
|
997
997
|
const { getFilename: a, exportAssets: o } = s, n = b(e, a(t));
|
|
998
|
-
if (await F(M(n), { recursive: !0 }), await
|
|
999
|
-
const i =
|
|
998
|
+
if (await F(M(n), { recursive: !0 }), await ae(n, z.stringify(t)), o) {
|
|
999
|
+
const i = ne(
|
|
1000
1000
|
t,
|
|
1001
|
-
(c) => typeof c == "string" && (Te.test(c) ||
|
|
1001
|
+
(c) => typeof c == "string" && (Te.test(c) || X.test(c))
|
|
1002
1002
|
).map((c) => {
|
|
1003
1003
|
const I = Ae(t, c);
|
|
1004
1004
|
return Qe(I);
|
|
@@ -1006,27 +1006,27 @@ async function se(t, e, s) {
|
|
|
1006
1006
|
await cs(i, M(n));
|
|
1007
1007
|
}
|
|
1008
1008
|
}
|
|
1009
|
-
const
|
|
1009
|
+
const Ie = new Oe({
|
|
1010
1010
|
max: 100,
|
|
1011
1011
|
ttl: 1 * 60 * 1e3
|
|
1012
1012
|
// 1 minute
|
|
1013
1013
|
});
|
|
1014
1014
|
async function Ge(t, e, s) {
|
|
1015
|
-
const a =
|
|
1015
|
+
const a = ne(
|
|
1016
1016
|
t,
|
|
1017
|
-
(i) => typeof i == "string" && (Te.test(i) ||
|
|
1017
|
+
(i) => typeof i == "string" && (Te.test(i) || X.test(i))
|
|
1018
1018
|
), o = ve(2), n = a.map(
|
|
1019
1019
|
(i) => o(async () => {
|
|
1020
1020
|
try {
|
|
1021
1021
|
const c = Ae(t, i), I = Qe(c);
|
|
1022
1022
|
for (const A of I) {
|
|
1023
|
-
const R = U(A), S = s.getFilePath(A, i), f = S ? `${S}:${R}` : R, p =
|
|
1023
|
+
const R = U(A), S = s.getFilePath(A, i), f = S ? `${S}:${R}` : R, p = Ie.get(f);
|
|
1024
1024
|
if (p) {
|
|
1025
|
-
|
|
1025
|
+
X.test(c) || Me(t, i, p);
|
|
1026
1026
|
return;
|
|
1027
1027
|
}
|
|
1028
1028
|
const w = await rs(S, R, e);
|
|
1029
|
-
w && (
|
|
1029
|
+
w && (X.test(c) || Me(t, i, w), Ie.set(f, w));
|
|
1030
1030
|
}
|
|
1031
1031
|
} catch (c) {
|
|
1032
1032
|
d.error(`Failed to process upload for path ${i.join(".")}:`, c.message || c.reason);
|
|
@@ -1122,19 +1122,19 @@ async function ls(t, {
|
|
|
1122
1122
|
const h = b(w, "routes");
|
|
1123
1123
|
await F(h, { recursive: !0 });
|
|
1124
1124
|
for (const { locale: r, slug: u, page: m } of p)
|
|
1125
|
-
await
|
|
1126
|
-
getFilename: () => `${
|
|
1125
|
+
await te(m, O, {
|
|
1126
|
+
getFilename: () => `${re(u) || "index"}.${r}.yml`,
|
|
1127
1127
|
exportAssets: e
|
|
1128
1128
|
});
|
|
1129
1129
|
for (const r of f)
|
|
1130
|
-
await
|
|
1130
|
+
await te(r, h, {
|
|
1131
1131
|
// getFilename: () => `${sanitizeSlug(route.path)}.yml`,
|
|
1132
|
-
getFilename: () => `${
|
|
1132
|
+
getFilename: () => `${re(r.path) || "index"}.yml`,
|
|
1133
1133
|
exportAssets: e
|
|
1134
1134
|
});
|
|
1135
1135
|
for (const r of c) {
|
|
1136
1136
|
const u = t.components[r]?.data;
|
|
1137
|
-
u && await
|
|
1137
|
+
u && await te(u, P, {
|
|
1138
1138
|
getFilename: (m) => `${m.name || "unnamed"}.${m.id}.yml`,
|
|
1139
1139
|
exportAssets: e
|
|
1140
1140
|
});
|
|
@@ -1176,16 +1176,16 @@ async function ls(t, {
|
|
|
1176
1176
|
supportedLocales: t.supportedLocales,
|
|
1177
1177
|
config: t.config
|
|
1178
1178
|
};
|
|
1179
|
-
await
|
|
1179
|
+
await ae(D, z.stringify(g));
|
|
1180
1180
|
const y = b(w, "config.source.json");
|
|
1181
|
-
if (o && await
|
|
1181
|
+
if (o && await ae(y, JSON.stringify(o)), n) {
|
|
1182
1182
|
const r = b(w, "resources"), u = b(r, "components");
|
|
1183
1183
|
await F(u, { recursive: !0 });
|
|
1184
1184
|
for (const $ of Object.keys(t?.resources?.components ?? {}).filter(
|
|
1185
1185
|
(k) => c.includes(k)
|
|
1186
1186
|
)) {
|
|
1187
1187
|
const k = t.resources?.components?.[$]?.component;
|
|
1188
|
-
k && await
|
|
1188
|
+
k && await te(k, u, {
|
|
1189
1189
|
getFilename: (G) => `${G.name || "unnamed"}.${G.id}.yml`,
|
|
1190
1190
|
exportAssets: e
|
|
1191
1191
|
});
|
|
@@ -1201,9 +1201,9 @@ async function ls(t, {
|
|
|
1201
1201
|
const G = k.renderer?.chunks ?? [];
|
|
1202
1202
|
if (G?.length > 0)
|
|
1203
1203
|
for (const q of G) {
|
|
1204
|
-
const ke = b(m, q),
|
|
1204
|
+
const ke = b(m, q), ue = v?.[q];
|
|
1205
1205
|
try {
|
|
1206
|
-
|
|
1206
|
+
ue && await x(ue) && !await x(ke) && await At(ue, ke);
|
|
1207
1207
|
} catch (rt) {
|
|
1208
1208
|
d.error(`copy chunk ${q} error`, rt.message);
|
|
1209
1209
|
}
|
|
@@ -1218,21 +1218,21 @@ async function Ze(t, { importAssets: e, includeResources: s } = {}) {
|
|
|
1218
1218
|
return null;
|
|
1219
1219
|
let a, o = !1;
|
|
1220
1220
|
try {
|
|
1221
|
-
(await
|
|
1222
|
-
const i = (await
|
|
1221
|
+
(await se(t)).isDirectory() ? a = t : /\.(tgz|gz|tar)$/.test(t) && (o = !0, a = Xe(), await Dt({ file: t, C: a }));
|
|
1222
|
+
const i = (await he("**/.blocklet/pages/pages.config.yml", { cwd: a, absolute: !0 }))[0], c = i && b(M(i), "../../pages"), I = i && b(M(i), "../../components"), A = i && b(M(i), "../../routes");
|
|
1223
1223
|
if (!i)
|
|
1224
1224
|
return null;
|
|
1225
|
-
const R = await
|
|
1225
|
+
const R = await Z(i, "utf-8"), S = z.parse(R), f = async (g, y, r) => {
|
|
1226
1226
|
let u = b(g, `${y}${r ? `.${r}` : ""}.yml`);
|
|
1227
|
-
if (!await x(u) && (u = b(g, y, `index${r ? `.${r}` : ""}.yml`), !await x(u)) || !(await
|
|
1227
|
+
if (!await x(u) && (u = b(g, y, `index${r ? `.${r}` : ""}.yml`), !await x(u)) || !(await se(u)).isFile())
|
|
1228
1228
|
return null;
|
|
1229
|
-
const v = await
|
|
1229
|
+
const v = await Z(u, "utf-8");
|
|
1230
1230
|
return z.parse(v);
|
|
1231
1231
|
}, p = async (g, y) => {
|
|
1232
1232
|
try {
|
|
1233
|
-
const u = (await
|
|
1233
|
+
const u = (await he(`*.${y}.yml`, { cwd: g, absolute: !0 }))[0];
|
|
1234
1234
|
if (!u) return null;
|
|
1235
|
-
const m = await
|
|
1235
|
+
const m = await Z(u, "utf-8");
|
|
1236
1236
|
return z.parse(m);
|
|
1237
1237
|
} catch (r) {
|
|
1238
1238
|
d.error("parse component error", r);
|
|
@@ -1240,9 +1240,9 @@ async function Ze(t, { importAssets: e, includeResources: s } = {}) {
|
|
|
1240
1240
|
return null;
|
|
1241
1241
|
}, w = async (g, y) => {
|
|
1242
1242
|
let r = b(g, `${y}.yml`);
|
|
1243
|
-
if (!await x(r) && (r = b(g, y, "index.yml"), !await x(r)) || !(await
|
|
1243
|
+
if (!await x(r) && (r = b(g, y, "index.yml"), !await x(r)) || !(await se(r)).isFile())
|
|
1244
1244
|
return null;
|
|
1245
|
-
const m = await
|
|
1245
|
+
const m = await Z(r, "utf-8");
|
|
1246
1246
|
return z.parse(m);
|
|
1247
1247
|
}, O = L(
|
|
1248
1248
|
await Promise.all(
|
|
@@ -1250,7 +1250,7 @@ async function Ze(t, { importAssets: e, includeResources: s } = {}) {
|
|
|
1250
1250
|
const y = L(
|
|
1251
1251
|
await Promise.all(
|
|
1252
1252
|
S.supportedLocales.map(async ({ locale: m }) => {
|
|
1253
|
-
const v = c ? await f(c,
|
|
1253
|
+
const v = c ? await f(c, re(g), m) : void 0;
|
|
1254
1254
|
if (v)
|
|
1255
1255
|
return { locale: m, page: v };
|
|
1256
1256
|
const $ = c ? await f(c, g, m) : void 0;
|
|
@@ -1304,7 +1304,7 @@ async function Ze(t, { importAssets: e, includeResources: s } = {}) {
|
|
|
1304
1304
|
), P = L(
|
|
1305
1305
|
await Promise.all(
|
|
1306
1306
|
(S?.routes || []).map(async ({ path: g }) => {
|
|
1307
|
-
const y = A ? await w(A,
|
|
1307
|
+
const y = A ? await w(A, re(g)) : void 0;
|
|
1308
1308
|
return {
|
|
1309
1309
|
...y,
|
|
1310
1310
|
id: y?.id || Ue(),
|
|
@@ -1350,7 +1350,7 @@ async function Ze(t, { importAssets: e, includeResources: s } = {}) {
|
|
|
1350
1350
|
g(`upload ${u.length} page assets`);
|
|
1351
1351
|
}
|
|
1352
1352
|
})
|
|
1353
|
-
]), g("upload assets done"),
|
|
1353
|
+
]), g("upload assets done"), Ie.clear(), global.gc && global.gc();
|
|
1354
1354
|
} catch (y) {
|
|
1355
1355
|
g("Error during asset import:", y);
|
|
1356
1356
|
}
|
|
@@ -1399,7 +1399,7 @@ async function Ve(t, e, {
|
|
|
1399
1399
|
for (const p of c ?? []) {
|
|
1400
1400
|
const w = I?.[p];
|
|
1401
1401
|
if (w?.params && w?.params.length > 0 && w?.paramsOptions && w?.paramsOptions.length > 0) {
|
|
1402
|
-
const O =
|
|
1402
|
+
const O = Ee({
|
|
1403
1403
|
basePath: w.path,
|
|
1404
1404
|
params: w.params,
|
|
1405
1405
|
routeId: w.id,
|
|
@@ -1444,7 +1444,7 @@ async function Ve(t, e, {
|
|
|
1444
1444
|
}
|
|
1445
1445
|
if (e.pageIds.includes(p)) {
|
|
1446
1446
|
if (d.info("has need update page", p), a === "replace")
|
|
1447
|
-
e.pages[p] =
|
|
1447
|
+
e.pages[p] = fe({
|
|
1448
1448
|
page: P,
|
|
1449
1449
|
route: O,
|
|
1450
1450
|
state: t,
|
|
@@ -1453,7 +1453,7 @@ async function Ve(t, e, {
|
|
|
1453
1453
|
}), d.info("replace page", p);
|
|
1454
1454
|
else if (a === "byUpdateTime") {
|
|
1455
1455
|
const h = e.pages[O.id];
|
|
1456
|
-
(!h || O.updatedAt && O.updatedAt > h.updatedAt) && (e.pages[p] =
|
|
1456
|
+
(!h || O.updatedAt && O.updatedAt > h.updatedAt) && (e.pages[p] = fe({
|
|
1457
1457
|
page: P,
|
|
1458
1458
|
route: O,
|
|
1459
1459
|
state: t,
|
|
@@ -1462,7 +1462,7 @@ async function Ve(t, e, {
|
|
|
1462
1462
|
}), d.info("replace page by update time", p));
|
|
1463
1463
|
}
|
|
1464
1464
|
} else
|
|
1465
|
-
e.pageIds.push(p), e.pages[p] =
|
|
1465
|
+
e.pageIds.push(p), e.pages[p] = fe({
|
|
1466
1466
|
page: P,
|
|
1467
1467
|
route: O,
|
|
1468
1468
|
state: t,
|
|
@@ -1501,7 +1501,7 @@ async function Ve(t, e, {
|
|
|
1501
1501
|
e.routeIds.push(f.id), e.routes[f.id] = f;
|
|
1502
1502
|
}
|
|
1503
1503
|
}
|
|
1504
|
-
if (e.supportedLocales.splice(0, e.supportedLocales.length), e.supportedLocales.push(...
|
|
1504
|
+
if (e.supportedLocales.splice(0, e.supportedLocales.length), e.supportedLocales.push(...be(A)), o)
|
|
1505
1505
|
for (const S of Object.keys(e.components))
|
|
1506
1506
|
delete e.components[S];
|
|
1507
1507
|
let R = JSON.parse(JSON.stringify(t.components));
|
|
@@ -1550,7 +1550,7 @@ const et = lt(
|
|
|
1550
1550
|
subdir: "getPropertiesFromCode"
|
|
1551
1551
|
}
|
|
1552
1552
|
);
|
|
1553
|
-
let
|
|
1553
|
+
let ie, Q, ce, le;
|
|
1554
1554
|
const tt = () => Et({
|
|
1555
1555
|
types: [
|
|
1556
1556
|
{ did: Je, type: Fe },
|
|
@@ -1559,7 +1559,7 @@ const tt = () => Et({
|
|
|
1559
1559
|
}), ps = async () => {
|
|
1560
1560
|
const t = tt(), e = {};
|
|
1561
1561
|
for (const s of t) {
|
|
1562
|
-
const o = (await
|
|
1562
|
+
const o = (await he("**/.blocklet/pages/pages.config.yml", {
|
|
1563
1563
|
cwd: s.path,
|
|
1564
1564
|
absolute: !0
|
|
1565
1565
|
}))[0], n = o && b(M(o), "../../chunks");
|
|
@@ -1572,14 +1572,14 @@ const tt = () => Et({
|
|
|
1572
1572
|
return e;
|
|
1573
1573
|
};
|
|
1574
1574
|
function st() {
|
|
1575
|
-
return
|
|
1575
|
+
return ie = (async () => {
|
|
1576
1576
|
const t = tt();
|
|
1577
|
-
|
|
1577
|
+
Q = (await Promise.all(
|
|
1578
1578
|
t.map(async (s) => {
|
|
1579
1579
|
const a = s.path ? await Ze(s.path, { importAssets: !1 }) : void 0;
|
|
1580
1580
|
return a ? { blockletId: s.did, state: a, blockletTitle: s.title } : void 0;
|
|
1581
1581
|
})
|
|
1582
|
-
)).filter((s) => !!s),
|
|
1582
|
+
)).filter((s) => !!s), ce = Q.reduce(
|
|
1583
1583
|
(s, a) => Object.assign(
|
|
1584
1584
|
s,
|
|
1585
1585
|
Object.fromEntries(
|
|
@@ -1588,7 +1588,7 @@ function st() {
|
|
|
1588
1588
|
),
|
|
1589
1589
|
{}
|
|
1590
1590
|
);
|
|
1591
|
-
const e =
|
|
1591
|
+
const e = Q.reduce(
|
|
1592
1592
|
(s, a) => Object.assign(
|
|
1593
1593
|
s,
|
|
1594
1594
|
Object.fromEntries(
|
|
@@ -1597,7 +1597,7 @@ function st() {
|
|
|
1597
1597
|
),
|
|
1598
1598
|
{}
|
|
1599
1599
|
);
|
|
1600
|
-
|
|
1600
|
+
le = Object.fromEntries(
|
|
1601
1601
|
await Promise.all(
|
|
1602
1602
|
Object.entries(e).map(async ([s, a]) => {
|
|
1603
1603
|
const o = await et(a.component);
|
|
@@ -1611,7 +1611,7 @@ function st() {
|
|
|
1611
1611
|
})
|
|
1612
1612
|
)
|
|
1613
1613
|
);
|
|
1614
|
-
})(),
|
|
1614
|
+
})(), ie;
|
|
1615
1615
|
}
|
|
1616
1616
|
function us(t) {
|
|
1617
1617
|
const e = Pe(
|
|
@@ -1619,22 +1619,22 @@ function us(t) {
|
|
|
1619
1619
|
await st().catch((s) => {
|
|
1620
1620
|
d.error("load resource states error", { error: s });
|
|
1621
1621
|
}), await t?.({
|
|
1622
|
-
states:
|
|
1623
|
-
pages:
|
|
1624
|
-
components:
|
|
1622
|
+
states: Q,
|
|
1623
|
+
pages: ce,
|
|
1624
|
+
components: le
|
|
1625
1625
|
});
|
|
1626
1626
|
},
|
|
1627
1627
|
3e3,
|
|
1628
1628
|
// 3s
|
|
1629
1629
|
{ leading: !1, trailing: !0 }
|
|
1630
1630
|
);
|
|
1631
|
-
return e(), E.events.on(E.Events.componentAdded, e), E.events.on(E.Events.componentRemoved, e), E.events.on(E.Events.componentStarted, e), E.events.on(E.Events.componentStopped, e), E.events.on(E.Events.componentUpdated, e), E.events.on(
|
|
1632
|
-
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(
|
|
1631
|
+
return e(), E.events.on(E.Events.componentAdded, e), E.events.on(E.Events.componentRemoved, e), E.events.on(E.Events.componentStarted, e), E.events.on(E.Events.componentStopped, e), E.events.on(E.Events.componentUpdated, e), E.events.on(Se, e), () => {
|
|
1632
|
+
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(Se, e);
|
|
1633
1633
|
};
|
|
1634
1634
|
}
|
|
1635
|
-
const at = Symbol.for("GLOBAL_RESOURCE_STATES_LISTENER_KEY"), ot = Symbol.for("GLOBAL_ENV_UPDATE_LISTENER_KEY"),
|
|
1636
|
-
|
|
1637
|
-
|
|
1635
|
+
const at = Symbol.for("GLOBAL_RESOURCE_STATES_LISTENER_KEY"), ot = Symbol.for("GLOBAL_ENV_UPDATE_LISTENER_KEY"), pe = globalThis;
|
|
1636
|
+
pe[at]?.();
|
|
1637
|
+
pe[at] = us(async ({ pages: t, components: e }) => {
|
|
1638
1638
|
const s = await C.getProjectIds();
|
|
1639
1639
|
d.info(`start update resource states projects(${s.length})`, s);
|
|
1640
1640
|
const a = ve(10);
|
|
@@ -1659,8 +1659,8 @@ ue[at] = us(async ({ pages: t, components: e }) => {
|
|
|
1659
1659
|
d.error("update resource states failed:", o);
|
|
1660
1660
|
});
|
|
1661
1661
|
});
|
|
1662
|
-
|
|
1663
|
-
|
|
1662
|
+
pe[ot]?.();
|
|
1663
|
+
pe[ot] = () => {
|
|
1664
1664
|
const t = () => {
|
|
1665
1665
|
C.pageUrlMapCache.clear(), d.info("[Cache CLEAR ALL] clear all page url map cache by env update");
|
|
1666
1666
|
};
|
|
@@ -1688,42 +1688,43 @@ async function nt({
|
|
|
1688
1688
|
d.info(`projectId: ${t} not found in sharedInstances`);
|
|
1689
1689
|
return;
|
|
1690
1690
|
}
|
|
1691
|
-
|
|
1692
|
-
a.syncedStore.resources.
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1691
|
+
a.transact(async () => {
|
|
1692
|
+
if (a.syncedStore.resources.pages = e, (await N.findByPk(t))?.useAllResources)
|
|
1693
|
+
a.syncedStore.resources.components = s;
|
|
1694
|
+
else {
|
|
1695
|
+
const l = (await De.findAll({ where: { projectId: t } })).map((c) => c.componentId), i = Object.fromEntries(
|
|
1696
|
+
Object.entries(s || {}).filter(([c]) => l.includes(c))
|
|
1697
|
+
);
|
|
1698
|
+
a.syncedStore.resources.components = i;
|
|
1699
|
+
}
|
|
1700
|
+
}), d.info(`update [${t}] resource states:`, {
|
|
1700
1701
|
pages: Object.keys(a.syncedStore.resources.pages || {}).length,
|
|
1701
1702
|
components: Object.keys(a.syncedStore.resources.components || {}).length
|
|
1702
1703
|
});
|
|
1703
1704
|
}
|
|
1704
|
-
const
|
|
1705
|
+
const ge = /* @__PURE__ */ new Map();
|
|
1705
1706
|
async function ds(t) {
|
|
1706
|
-
if (!
|
|
1707
|
+
if (!ge.has(t)) {
|
|
1707
1708
|
const e = Pe(async (s) => nt({
|
|
1708
1709
|
projectId: s,
|
|
1709
|
-
pages:
|
|
1710
|
-
components:
|
|
1710
|
+
pages: ce,
|
|
1711
|
+
components: le
|
|
1711
1712
|
}), 3e3);
|
|
1712
|
-
|
|
1713
|
+
ge.set(t, e);
|
|
1713
1714
|
}
|
|
1714
|
-
return
|
|
1715
|
+
return ge.get(t)(t);
|
|
1715
1716
|
}
|
|
1716
1717
|
async function Js() {
|
|
1717
|
-
d.info("trigger reload all project resource"), E.events.emit(
|
|
1718
|
+
d.info("trigger reload all project resource"), E.events.emit(Se);
|
|
1718
1719
|
}
|
|
1719
1720
|
async function Ys({
|
|
1720
1721
|
ensureLoaded: t = !0
|
|
1721
1722
|
} = {}) {
|
|
1722
|
-
return t && (
|
|
1723
|
+
return t && (ie ??= st(), await ie), { states: Q, pages: ce, components: le };
|
|
1723
1724
|
}
|
|
1724
1725
|
export {
|
|
1725
1726
|
Je as C,
|
|
1726
|
-
|
|
1727
|
+
N as P,
|
|
1727
1728
|
Fe as R,
|
|
1728
1729
|
C as S,
|
|
1729
1730
|
J as a,
|
package/lib/es/resources.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { i as A, a as T, l as D } from "./chunks/components-CcZk17uO.js";
|
|
2
|
-
import { P as E, C as L, R as M, S as b, 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 b, t as F, c as J, g as X } from "./chunks/site-state-DY7YJ7F1.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-CcZk17uO.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-DY7YJ7F1.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.3",
|
|
4
4
|
"description": "Pages Kit inner components library",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -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.3",
|
|
205
|
+
"@blocklet/pages-kit-block-studio": "^0.7.3"
|
|
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-CnPdZJ2Z.js"),G=require("@syncedstore/core"),rt=require("yjs"),it=require("@blocklet/pages-kit/utils/data-source"),se=require("@blocklet/pages-kit/utils/route"),ct=require("lodash/cloneDeep"),lt=require("@blocklet/sdk/lib/config"),ee=require("fs"),f=require("path"),Me=require("@blocklet/pages-kit/utils/common"),ut=require("@blocklet/pages-kit/utils/page-model"),dt=require("@blocklet/pages-kit/utils/property"),je=require("@blocklet/sdk/lib/component"),pt=require("@reactivedata/reactive"),C=require("fs/promises"),ne=require("glob"),ft=require("lib0/decoding"),gt=require("lib0/encoding"),mt=require("lodash/debounce"),ht=require("lodash/get"),yt=require("lodash/isEmpty"),St=require("lodash/set"),wt=require("lodash/union"),Ce=require("lru-cache"),It=require("p-limit"),A=require("sequelize"),bt=require("stream/promises"),Et=require("tar"),N=require("ufo"),Pt=require("wait-on"),H=require("y-protocols/awareness"),ge=require("y-protocols/sync"),At=require("yaml"),$e=require("./html-dP5_4zu1.js");require("sqlite3");require("@blocklet/pages-kit/types/state");const $=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 F=le(rt),W=$(ct),E=$(lt),V=$(ee),Ne=$(f),me=le(ft),k=le(gt),Oe=$(mt),De=$(ht),Te=$(yt),Fe=$(St),jt=$(wt),Re=$(It),Ct=$(Pt),K=le(At),Ot=A.DataTypes.sqlite.DATE.parse;A.DataTypes.sqlite.DATE.parse=(t,e)=>typeof t=="number"?new Date(t):Ot(t,e);const B=new A.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});B.query("PRAGMA journal_mode = WAL;");B.query("PRAGMA synchronous = normal;");B.query("PRAGMA journal_size_limit = 67108864;");B.query("PRAGMA cache_size = 10000;");process.on("SIGINT",async()=>{await B.close(),process.exit(0)});process.on("SIGTERM",async()=>{await B.close(),process.exit(0)});async function Dt(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 we=null;we&&clearInterval(we);we=setInterval(async()=>{u.logger.info("Start cleanupSqliteMemory"),await Dt(B,u.databaseUrl),u.logger.info("End cleanupSqliteMemory")},60*1e3*10);const Tt="z8iZiDFg3vkkrPwsiba1TLXy3H9XHzFERsP8o",Ie="page",be="trigger-reload-project-resource",ve=Tt,Rt="z2qa7BQdkEb3TwYyEYC1psK6uvmGnHSUHt5RM",vt="z8iZiDFg3vkkrPwsiba1TLXy3H9XHzFERsP8o";class ke extends A.Model{}ke.init({id:{type:A.DataTypes.UUID,allowNull:!1,primaryKey:!0,defaultValue:A.DataTypes.UUIDV4},projectId:{type:A.DataTypes.UUID,allowNull:!1},componentId:{type:A.DataTypes.STRING,allowNull:!1}},{sequelize:B,tableName:"ProjectComponents",timestamps:!1});const kt="SLUG_INVALID",J=t=>({error:"slugInvalid",code:kt,field:"slug",message:t}),_t={error:"slugRequired",code:"SLUG_REQUIRED",field:"slug",message:()=>"Project slug is required"},Lt={error:"slugAlreadyExists",code:"SLUG_EXISTS",field:"slug",message:t=>`Project slug "${t}" already exists`},Ut=[/\.\./,/<[^>]*>/,/%[0-9a-f]{2}/i,/[<>'"%;{}()\\]/,/\x00/,/\n|\r|\t|\v|\f/,/[^a-zA-Z0-9-_@/\\:]/],qe=t=>{if(!t)return"";if(t==="/")return"/";const e=N.withoutTrailingSlash(t);return N.withLeadingSlash(e)||"/"},Mt=t=>t.did===vt;class U extends A.Model{static async getProjectByIdOrSlug(e,a){return e?U.findOne({where:{[A.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 _t;const s=e==="/"?"/":N.withoutTrailingSlash(N.withLeadingSlash(e)),n=qe(s);if(s!=="/"&&s.endsWith("/"))return J(i=>`Project slug "${i}" cannot end with /`);if(/\/{2,}/.test(s))return J(i=>`Project slug "${i}" cannot contain consecutive /`);if(/\s/.test(s))return J(i=>`Project slug "${i}" cannot contain whitespace`);if(Ut.some(i=>i.test(s)))return J(i=>`Project slug "${i}" contains invalid characters`);if(E.default.components?.filter(i=>i.mountPoint&&!Mt(i)).some(i=>qe(i.mountPoint)===n))return J(i=>`Project slug "${i}" conflicts with existing blocklet`);const l=await U.findOne({where:{slug:s}});return l&&l?.id!==a?Lt:null}}U.init({id:{type:A.DataTypes.UUID,defaultValue:A.DataTypes.UUIDV4,primaryKey:!0},name:{type:A.DataTypes.STRING,allowNull:!1},description:A.DataTypes.TEXT,createdAt:A.DataTypes.DATE,updatedAt:A.DataTypes.DATE,createdBy:{type:A.DataTypes.STRING,allowNull:!1},updatedBy:{type:A.DataTypes.STRING,allowNull:!1},slug:A.DataTypes.STRING,icon:A.DataTypes.STRING,pinnedAt:A.DataTypes.DATE,useAllResources:A.DataTypes.BOOLEAN,npmSecret:A.DataTypes.STRING,relatedBlocklets:{type:A.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:A.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:A.DataTypes.JSON,allowNull:!0}},{sequelize:B,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:{[A.Op.ne]:null}}}]});U.hasMany(ke,{foreignKey:"projectId",as:"components"});async function q(t){try{return await V.default.promises.access(t,V.default.constants.F_OK),!0}catch{return!1}}function Ge(t,e){return new Promise((a,s)=>{const n=V.default.createReadStream(t),o=V.default.createWriteStream(e);n.on("error",s),o.on("error",s),o.on("finish",a),n.pipe(o)})}async function Ve(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 n=Ne.default.join(t,s.name),o=Ne.default.join(e,s.name);s.isDirectory()?await Ve(n,o):await Ge(n,o)}}async function $t(t,e){(await V.default.promises.stat(t)).isDirectory()?await Ve(t,e):await Ge(t,e)}function oe(t){t.observeDeep(e=>{e.some(a=>a.changes.keys.has("updatedAt")||a.changes.keys.has("publishedAt"))||t.set("updatedAt",new Date().toISOString())})}function ze(){return ee.mkdtempSync(f.join(E.default.env.dataDir,"tmp-"))}function re(t,e,a=[]){return Array.isArray(t)?t.flatMap((s,n)=>re(s,e,[...a,n])):typeof t=="object"?t===null?[]:Object.entries(t).flatMap(([s,n])=>re(n,e,[...a,s])):e(t)?[a]:[]}function L(t){return t.filter(e=>e!=null)}function Nt(t){t.pages&&Object.keys(t.pages).forEach(a=>{const s=G.getYjsValue(t.pages[a]);s&&s instanceof F.Map&&oe(s)});const e=G.getYjsValue(t.pages);e&&e instanceof F.Map&&e.observe(a=>{a.changes.keys.forEach((s,n)=>{if(s.action==="add"){const o=G.getYjsValue(t.pages[n]);o&&o instanceof F.Map&&oe(o)}})})}function Ft(t){t.routes&&Object.keys(t.routes).forEach(a=>{const s=G.getYjsValue(t.routes?.[a]);s&&s instanceof F.Map&&oe(s)});const e=G.getYjsValue(t.routes);e&&e instanceof F.Map&&e.observe(a=>{a.changes.keys.forEach((s,n)=>{if(s.action==="add"){const o=G.getYjsValue(t.routes?.[n]);o&&o instanceof F.Map&&oe(o)}})})}function qt(t,e){for(const a of e||Object.keys(t.routes||{})){let s=a,n=[];if(a.includes("-")){const[o,...l]=a.split("-");s=o,n=l||[]}if(t.routes?.[s]!==void 0){t.routes[s].publishedAt=new Date().toISOString();const o=t.routes[s];if(!o||!o.params||o.params.length===0)continue;if(a.includes("-")&&n.length>0){const l=se.getRouteMetaDataByOptionIds(n,o);l&&(l.publishedAt=new Date().toISOString())}if(!e){const l=se.generateParamCombinations({basePath:o.path,params:o.params,routeId:o.id,paramsOptions:o.paramsOptions,currentIndex:0,currentParams:[],currentOptionIds:[],result:[]});for(const i of l)i.routeMetaData??={},i.routeMetaData.publishedAt=new Date().toISOString()}}}}function he({page:t,route:e,state:a,routeId:s,routePathInfo:n}){u.logger.info(`Executing datasource data assembly, routeId: ${s}, routePathInfo: ${JSON.stringify(n)}`);const o={...W.default(t),id:s,slug:n?.path??e.path,createdAt:e.createdAt,updatedAt:n?.routeMetaData?.updatedAt??e.updatedAt,publishedAt:n?.routeMetaData?.publishedAt??e.publishedAt,isPublic:(n?.routeMetaData?.isPublic??e.isPublic)&&e.isPublic};for(const l of a.supportedLocales){if(e.dataSource){let i=e.id;n&&(i=n.paramOptionIds.join("-"));const c=e.dataSource.pathDataMappings?.[i]?.dataCache?.[l.locale]??e.dataSource.pathDataMappings?.[i]?.dataCache?.[a.config.defaultLocale||"en"];if(!c)continue;it.setPageDataSource(o,a,l.locale,c)}n&&n.routeMetaData&&(n.routeMetaData.publishedAt=new Date().toISOString())}return o}["true","1","yes","y"].includes(process.env.USE_FS_CACHE_HTML??"");const Bt=60*60*1e3,X=new Ce.LRUCache({max:300,ttl:Bt,ttlResolution:10*1e3,allowStale:!0});function xt(t,e=[]){let a=0;const s=Array.from(X.keys()),n=t.map(o=>N.withoutTrailingSlash(o));for(const o of s)for(const l of n){if($e.matchCacheKey(o,{currentPath:l})){X.delete(o),a++,u.logger.info(`[Cache CLEAR] key: ${o}`);break}for(const i of e)if($e.matchCacheKey(o,{currentPath:`/${i}${l}`})){X.delete(o),a++,u.logger.info(`[Cache CLEAR] key: ${o}`);break}}return u.logger.info(`[Cache CLEAR] cleared ${a} entries for paths:`,n),a}function Gt(){const t=X.size;return X.clear(),u.logger.info(`[Cache CLEAR ALL] cleared ${t} entries`),t}E.default.events.on(E.default.Events.envUpdate,Gt);const{uploadToMediaKit:Vt}=require("@blocklet/uploader-server"),_e=/^\w+(\w|-|\.)+\w+\.(jpe?g|png|gif|svg|bmp|webp|mp4|m4v|webm)$/,Q=/mediakit:\/\/([a-f0-9]{32}\.(jpe?g|png|gif|svg|bmp|webp|mp4|m4v|webm))/i,Be=/mediakit:\/\/([a-f0-9]{32}\.(jpe?g|png|gif|svg|bmp|webp|mp4|m4v|webm))/gi,zt=1e4,Kt=3e4,te=0,ye=1,Yt=0,Ht=1,Ee=E.default,z=f.join(process.env.BLOCKLET_DATA_DIR,"site-state"),Jt=["production","draft"],Wt=["production"];function ie(t){return t?.replace(/\//g,"|")||""}function Ke(){const t=Ee.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 j extends F.Doc{constructor(e){super(),this.options=e,ee.existsSync(this.draftYjsFilePath)&&F.applyUpdate(this,ee.readFileSync(this.draftYjsFilePath)),this.syncedStore=pt.reactive(G.syncedStore({pages:{},pageIds:[],components:{},supportedLocales:[],config:{},resources:{},routeIds:[],routes:{},dataSourceIds:[],dataSources:{}},this)),this.initObserver(),this.on("update",this.updateHandler),this.awareness=new H.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 pageUrlMapCache=new Ce.LRUCache({max:300,ttl:1e3*60*60*24});static periodicCheckTimer;static async safeDeleteProjectStateDir(e){if(!e)throw new Error("Should provide project context");try{const a=f.join(z,e),s=f.join(z,`@del-${e}`);await C.rename(a,s)}catch(a){u.logger.error("Failed to safe delete project state dir:",a)}}static async getProjectIds(){return(await U.findAll({attributes:["id"],raw:!0}))?.map(e=>e.id)}static get projectIds(){return ne.globSync("*/",{cwd:z,ignore:["@del-*","@tmp-*",".*","staging","production","@backup-*","undefined"]})}static get allShared(){return this.projectIds.map(e=>j.shared(e))}static shared(e){if(!e)throw new Error("Should provide project context");let a=j.sharedInstances[e];return a||(a=new j({path:f.join(z,e)}),j.sharedInstances[e]=a,a)}static async getProductionState(e){const a=await U.findByPk(e,{attributes:["productionState"]});if(Te.default(a?.productionState)){const s=f.join(z,e,"production"),n=await Le(s,{includeResources:!0})??Ke();if(!n?.config?.defaultLocale){n.config??={};const o=Ee.env.languages?.map(l=>({locale:l.code,name:l.name}))||[];n.config.defaultLocale=o[0]?.locale}return n}return a?.productionState}destroy(){this.cancelRelease(),this.save({flush:!0}),this.conns.forEach((a,s)=>this.closeConn(s)),this.awareness.destroy();const e=f.basename(this.options.path);delete j.sharedInstances[e],super.destroy()}initObserver(){Nt(this.syncedStore),Ft(this.syncedStore)}get draftYjsFilePath(){return f.join(this.options.path,"draft.yjs")}static async getStateByProjectId({projectId:e,mode:a,clone:s=!0}){if(a==="draft"){const n=j.shared(e);return s?W.default(n.syncedStore):n.syncedStore}return j.getProductionState(e)}async getState(e){if(e==="draft")return W.default(this.syncedStore);const a=f.basename(this.options.path);return j.getProductionState(a)}async setState(e,a){const s=await We(a,{exportAssets:!1,includeResources:!0}),n=this.getPublishDir(e);if(await C.mkdir(f.dirname(n),{recursive:!0}),await C.rm(n,{force:!0,recursive:!0}),await C.rename(s,n),e==="production"){const o=f.basename(this.options.path);j.pageUrlMapCache.delete(o);const l=W.default(a);await U.update({productionState:l},{where:{id:o}})}}getPublishDir(e){return f.join(this.options.path,e)}syncedStore;conns=new Map;awareness;releaseTimer;awarenessChangeHandler=({added:e,updated:a,removed:s},n)=>{const o=e.concat(a,s);if(n!==null){const c=this.conns.get(n);c&&(e.forEach(b=>{c.add(b)}),s.forEach(b=>{c.delete(b)}))}const l=k.createEncoder();k.writeVarUint(l,ye),k.writeVarUint8Array(l,H.encodeAwarenessUpdate(this.awareness,o));const i=k.toUint8Array(l);this.conns.forEach((c,b)=>this.send(b,i))};updateHandler=e=>{const a=k.createEncoder();k.writeVarUint(a,te),ge.writeUpdate(a,e);const s=k.toUint8Array(a);this.conns.forEach((n,o)=>this.send(o,s))};ensureDataStructure=()=>{this.transact(()=>{const{supportedLocales:e,pages:a,pageIds:s,config:n,routes:o,routeIds:l}=this.syncedStore;{const i=new Set(Object.keys(a));let c=0;for(;c<s.length;){const b=s[c];i.has(b)?(i.delete(b),c++):s.splice(c,1)}}{const i=new Set(Object.keys(o));let c=0;for(;c<l.length;){const b=l[c];i.has(b)?(i.delete(b),c++):l.splice(c,1)}}e.splice(0,e.length),e.push(...Ee.env.languages.map(i=>({locale:i.code,name:i.name}))),n.defaultLocale=e[0]?.locale;{let i=0;const c=new Set;for(;i<e.length;){const{locale:b}=e[i];c.has(b)?e.splice(i,1):(i++,c.add(b))}}})};send=(e,a)=>{e.readyState!==Yt&&e.readyState!==Ht&&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&&H.removeAwarenessStates(this.awareness,Array.from(a),null)}e.close(),this.checkAndScheduleRelease()};checkAndScheduleRelease(){this.conns.size===0&&this.scheduleRelease()}scheduleRelease(){this.cancelRelease();const e=f.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())},j.RELEASE_DELAY),u.logger.info(`[SiteState] scheduled release for project ${e} in ${j.RELEASE_DELAY/1e3}s`)}cancelRelease(){if(this.releaseTimer){clearTimeout(this.releaseTimer),this.releaseTimer=void 0;const e=f.basename(this.options.path);u.logger.info(`[SiteState] cancelled scheduled release for project ${e}`)}}autoSave=Oe.default(async()=>{await C.mkdir(f.dirname(this.draftYjsFilePath),{recursive:!0}),await C.writeFile(this.draftYjsFilePath,F.encodeStateAsUpdate(this))},zt);save=({flush:e=!1}={})=>{this.autoSave(),e&&this.autoSave.flush()};publish=async({mode:e,routes:a})=>{const s=f.basename(this.options.path);await nt(s);const n=await this.getState("draft"),o=await this.getState("production");await Ae(n,o,{routes:a,mergeMode:"replace",deleteRoutes:!0,publishMode:e}),o.config.publishedAt=new Date().getTime(),qt(this.syncedStore,a),await this.setState(e,o),await this.clearPageCacheForRoutes(a,o)};mergeState=async(e,a)=>{const s=JSON.parse(JSON.stringify(a));e.config.fontFamily??={};const n=s.config?.fontFamily,o=e.config?.fontFamily;e.config.fontFamily.title=n?.title||o?.title,e.config.fontFamily.description=n?.description||o?.description,await new Promise((l,i)=>{this.transact(async()=>{try{const c=await Ae(e,a);l(c)}catch(c){i(c)}})})};clearPageCacheForRoutes=async(e,a)=>{const s=f.basename(this.options.path),o=(await U.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 i=a.supportedLocales.map(O=>O.locale),c=[],b=l.filter(O=>a.pageIds?.includes(O));for(const O of b){const w=a.pages[O].slug;o&&o!==s&&(o==="/"?c.push(w):c.push(`/${o}${w}`)),c.push(`/${s}${w}`)}if(c.length>0)try{const O=xt(c,i);u.logger.info(`[SiteState] cleared ${O} page cache entries for project ${s}, routes:`,l)}catch{}j.pageUrlMapCache.delete(s)};addConnection=e=>{if(this.conns.has(e))return;this.cancelRelease(),e.binaryType="arraybuffer",this.conns.set(e,new Set),e.on("message",n=>this.messageListener(e,new Uint8Array(n)));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)}}},Kt);e.on("close",()=>{this.closeConn(e),clearInterval(s)}),e.on("pong",()=>{a=!0});{const n=k.createEncoder();k.writeVarUint(n,te),ge.writeSyncStep1(n,this),this.send(e,k.toUint8Array(n));const o=this.awareness.getStates();if(o.size>0){const l=k.createEncoder();k.writeVarUint(l,ye),k.writeVarUint8Array(l,H.encodeAwarenessUpdate(this.awareness,Array.from(o.keys()))),this.send(e,k.toUint8Array(l))}}};messageListener=(e,a)=>{try{const s=k.createEncoder(),n=me.createDecoder(a),o=me.readVarUint(n);switch(o){case te:k.writeVarUint(s,te),ge.readSyncMessage(n,s,this,null),k.length(s)>1&&(this.ensureDataStructure(),this.send(e,k.toUint8Array(s)));break;case ye:{H.applyAwarenessUpdate(this.awareness,me.readVarUint8Array(n),e);break}default:u.logger.warn(`Unsupported messageType ${o}`)}}catch(s){u.logger.error(s)}this.save()};static async pageUrlMap(e,a){u.logger.info(`[SiteState] get pageUrlMap, mode: ${e}, projectId: ${a}`);let s=[];a?s=[a]:s=await this.getProjectIds();let n={};if(e==="production"&&s?.length){const o=new Map(s?.map(l=>[l,!0])||[]);for(const l of s){const i=j.pageUrlMapCache.get(l);i&&(Object.assign(n,i),o.delete(l))}s=Array.from(o.keys())}if(s?.length){u.logger.info("[SiteState] find project infos from database, projectIds: ",s);const o=30,l=Re.default(5);for(let i=0;i<s.length;i+=o){const c=s.slice(i,i+o);u.logger.info(`[SiteState] processing project batch ${i/o+1}, ids: `,c);const b=await U.findAll({where:{id:{[A.Op.in]:c}},attributes:{exclude:["relatedBlocklets"]}});await Promise.all(b?.map(O=>l(async()=>{const R=O.id,w=O.slug||R,g={},d=e==="production"&&O?.productionState?O.productionState:await j.getStateByProjectId({projectId:O.id,mode:e,clone:!1}),I=jt.default(E.default.env.languages?.map(P=>P.code)||[],d.supportedLocales?.map(P=>P.locale)||[]),D=(P,y)=>{w&&(g[N.joinURL("/",w,P)]={...y,shouldRedirect:!0,mainPage:!0}),g[N.joinURL("/",R,P)]={...y,shouldRedirect:!0,mainPage:!0};for(const v of I){const h={...y,locale:v};g[N.joinURL("/",v,R,P)]=h,w&&(g[N.joinURL("/",v,w,P)]=h)}};if(e==="draft")for(const P of d.routeIds||[]){const y=d?.routes?.[P];if(!y)continue;if(y.params&&y.params.length>0){const S=se.generateParamCombinations({basePath:y.path,params:y.params,routeId:y.id,paramsOptions:y.paramsOptions,currentIndex:0,currentParams:[],currentOptionIds:[],result:[]});for(const r of S){const p=r.path,m={projectId:R,projectSlug:w,pageSlug:p,pageId:y.displayTemplateId||"",routeId:P,defaultLocale:I?.[0],locales:I,publishedAt:d.config.publishedAt,isPublic:y.isPublic&&r?.routeMetaData?.isPublic};D(p,m)}}const v=y.path,h={projectId:R,projectSlug:w,pageSlug:v,pageId:y.displayTemplateId||"",routeId:P,defaultLocale:I?.[0],locales:I,publishedAt:d.config.publishedAt,isPublic:y.isPublic};D(v,h)}for(const P of d.pageIds||[]){const y=d.pages[P];if(!y||e==="production"&&!y.isPublic)continue;const v=y.slug,h=O.slug||R,S={projectId:R,projectSlug:h,pageSlug:v,pageId:P,defaultLocale:I?.[0],locales:I,publishedAt:d.config.publishedAt,isPublic:y.isPublic,templateConfig:y.templateConfig};D(v,S)}e==="production"&&j.pageUrlMapCache.set(R,g),n={...n,...g}})))}}return u.logger.info("[SiteState] success get pageUrlMap"),n}getDocumentSize(){return F.encodeStateAsUpdate(this).byteLength}static getInstancesSizeInfo(){const e=[];for(const[a,s]of Object.entries(j.sharedInstances)){const n=s.getDocumentSize();e.push({projectId:a,sizeInBytes:n,sizeInMB:`${(n/(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(j.sharedInstances).length,a=[],s=[];for(const[n,o]of Object.entries(j.sharedInstances))o.conns.size===0?a.push({projectId:n,instance:o}):s.push({projectId:n,connections:o.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(o=>o.projectId));let n=0;for(const{projectId:o,instance:l}of a)try{u.logger.info(`[SiteState] releasing instance due to periodic check: ${o}`),l.destroy(),n++}catch(i){u.logger.error(`[SiteState] failed to release instance ${o} during periodic check:`,i)}u.logger.info(`[SiteState] periodic check completed: ${n}/${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 Xt(t,e,a){if(!t||!await q(t)||!(await C.lstat(t)).isFile())return null;let n=a[t];return n||(n=(async()=>{try{return(await Vt({filePath:t,fileName:e}))?.data?.filename}catch(o){return u.logger.error(`Failed to upload asset ${t}:`,o),null}})(),a[t]=n),n}const Ye=async(t,e)=>{const a=f.basename(t),s=await je.call({name:ve,path:N.joinURL("/uploads",a),responseType:"stream",method:"GET"});if(s.status>=200&&s.status<400){const n=ee.createWriteStream(e);await bt.pipeline(s.data,n)}else throw new Error(`download asset failed ${s.status}`)},He=async(t,e)=>{await Promise.all(t.map(async a=>{try{await Ye(a,f.join(e,f.basename(a)))}catch(s){u.logger.error(`Failed to export assets: ${a}, ${s}`)}}))};function Je(t){return _e.test(t)?[t]:Q.test(t)?(Be.lastIndex=0,Array.from(t.matchAll(Be)).map(a=>a[1]).filter(a=>!!a)):[]}async function ae(t,e,a){const{getFilename:s,exportAssets:n}=a,o=f.join(e,s(t));if(await C.mkdir(f.dirname(o),{recursive:!0}),await C.writeFile(o,K.stringify(t)),n){const i=re(t,c=>typeof c=="string"&&(_e.test(c)||Q.test(c))).map(c=>{const b=De.default(t,c);return Je(b)}).flat().filter(Boolean);await He(i,f.dirname(o))}}const Pe=new Ce.LRUCache({max:100,ttl:1*60*1e3});async function xe(t,e,a){const s=re(t,i=>typeof i=="string"&&(_e.test(i)||Q.test(i))),n=Re.default(2),o=s.map(i=>n(async()=>{try{const c=De.default(t,i),b=Je(c);for(const O of b){const R=f.basename(O),w=a.getFilePath(O,i),g=w?`${w}:${R}`:R,d=Pe.get(g);if(d){Q.test(c)||Fe.default(t,i,d);return}const I=await Xt(w,R,e);I&&(Q.test(c)||Fe.default(t,i,I),Pe.set(g,I))}}catch(c){u.logger.error(`Failed to process upload for path ${i.join(".")}:`,c.message||c.reason)}})),l=await Promise.allSettled(o);a.onFinish?.(l)}async function We(t,{exportAssets:e,pageIds:a="all",componentIds:s="all",rawConfig:n,includeResources:o=!1,routeIds:l="all"}={}){const i=a==="all"?t.pageIds:a,c=dt.getComponentDependencies({state:t,pageIds:i,componentIds:s==="all"?Object.keys(t.components):s});Object.entries(t.components).forEach(([r,p])=>{p.data?.renderer?.type==="component-template"&&c.push(r)});const b=l==="all"?t.routeIds:l,O=r=>({id:r.id,name:r.name,isTemplateSection:r.isTemplateSection??!1,templateDescription:r.templateDescription,component:r.component,config:r.config,visibility:r.visibility,sections:r?.sectionIds?L(r?.sectionIds?.map(p=>{const m=r.sections?.[p];return m&&O(m)})):void 0}),R=(r,p)=>({id:r.id,createdAt:r.createdAt,updatedAt:r.updatedAt,publishedAt:r.publishedAt,isPublic:r.isPublic??!0,templateConfig:r.templateConfig,meta:r.locales?.[p]??{},sections:L(r.sectionIds.map(m=>{const T=r.sections[m];return T&&O(T)})),dataSource:Object.fromEntries(Object.entries(r.dataSource||{}).map(([m,T])=>[m,T?.[p]??{}]))}),w=r=>({id:r.id,createdAt:r.createdAt,updatedAt:r.updatedAt,publishedAt:r.publishedAt,path:r.path,handler:r.handler,isPublic:r.isPublic??!0,params:r.params??[],enabledGenerate:r.enabledGenerate??!1,displayTemplateId:r.displayTemplateId,dataSource:r.dataSource}),g=L(b.map(r=>{const p=t.routes[r];return p&&w(p)})),d=L(t.supportedLocales.map(r=>r.locale).flatMap(r=>i.map(p=>{const m=t.pages[p];return m&&{locale:r,slug:m.slug,page:R(m,r)}}))),I=ze(),D=f.join(I,"pages");await C.mkdir(D,{recursive:!0});const P=f.join(I,"components");await C.mkdir(P,{recursive:!0});const y=f.join(I,"routes");await C.mkdir(y,{recursive:!0});for(const{locale:r,slug:p,page:m}of d)await ae(m,D,{getFilename:()=>`${ie(p)||"index"}.${r}.yml`,exportAssets:e});for(const r of g)await ae(r,y,{getFilename:()=>`${ie(r.path)||"index"}.yml`,exportAssets:e});for(const r of c){const p=t.components[r]?.data;p&&await ae(p,P,{getFilename:m=>`${m.name||"unnamed"}.${m.id}.yml`,exportAssets:e})}const v=f.join(I,".blocklet/pages/pages.config.yml");await C.mkdir(f.dirname(v),{recursive:!0});const h={pages:L(i.map(r=>{const p=t.pages[r];return p&&{id:r,slug:p.slug}})),routes:L(b.map(r=>{const p=t.routes[r];return p&&{id:r,path:p.path}})),components:L(c.map(r=>{const p=t.components[r]?.data;return p&&{id:r,name:p.name}})),...o?{resources:{components:L(Object.keys(t.resources?.components||{}).filter(r=>c.includes(r)).map(r=>({id:r,name:t.resources?.components?.[r]?.component?.name})))}}:{},supportedLocales:t.supportedLocales,config:t.config};await C.writeFile(v,K.stringify(h));const S=f.join(I,"config.source.json");if(n&&await C.writeFile(S,JSON.stringify(n)),o){const r=f.join(I,"resources"),p=f.join(r,"components");await C.mkdir(p,{recursive:!0});for(const M of Object.keys(t?.resources?.components??{}).filter(_=>c.includes(_))){const _=t.resources?.components?.[M]?.component;_&&await ae(_,p,{getFilename:x=>`${x.name||"unnamed"}.${x.id}.yml`,exportAssets:e})}const m=f.join(I,"chunks");await C.mkdir(m,{recursive:!0});const T=await Qt();for(const M of Object.keys(t?.resources?.components??{}).filter(_=>c.includes(_))){const _=t.resources?.components?.[M]?.component;if(_&&_.renderer?.type==="react-component"){const x=_.renderer?.chunks??[];if(x?.length>0)for(const Y of x){const Ue=f.join(m,Y),fe=T?.[Y];try{fe&&await q(fe)&&!await q(Ue)&&await C.copyFile(fe,Ue)}catch(ot){u.logger.error(`copy chunk ${Y} error`,ot.message)}}}}}return I}async function Le(t,{importAssets:e,includeResources:a}={}){if(!await q(t))return null;let s,n=!1;try{(await C.lstat(t)).isDirectory()?s=t:/\.(tgz|gz|tar)$/.test(t)&&(n=!0,s=ze(),await Et.x({file:t,C:s}));const i=(await ne.glob("**/.blocklet/pages/pages.config.yml",{cwd:s,absolute:!0}))[0],c=i&&f.join(f.dirname(i),"../../pages"),b=i&&f.join(f.dirname(i),"../../components"),O=i&&f.join(f.dirname(i),"../../routes");if(!i)return null;const R=await C.readFile(i,"utf-8"),w=K.parse(R),g=async(h,S,r)=>{let p=f.join(h,`${S}${r?`.${r}`:""}.yml`);if(!await q(p)&&(p=f.join(h,S,`index${r?`.${r}`:""}.yml`),!await q(p))||!(await C.lstat(p)).isFile())return null;const T=await C.readFile(p,"utf-8");return K.parse(T)},d=async(h,S)=>{try{const p=(await ne.glob(`*.${S}.yml`,{cwd:h,absolute:!0}))[0];if(!p)return null;const m=await C.readFile(p,"utf-8");return K.parse(m)}catch(r){u.logger.error("parse component error",r)}return null},I=async(h,S)=>{let r=f.join(h,`${S}.yml`);if(!await q(r)&&(r=f.join(h,S,"index.yml"),!await q(r))||!(await C.lstat(r)).isFile())return null;const m=await C.readFile(r,"utf-8");return K.parse(m)},D=L(await Promise.all(w.pages.map(async({slug:h})=>{const S=L(await Promise.all(w.supportedLocales.map(async({locale:m})=>{const T=c?await g(c,ie(h),m):void 0;if(T)return{locale:m,page:T};const M=c?await g(c,h,m):void 0;return M&&{locale:m,page:M}}))),r=S[0]?.page;if(!r)return null;const p=r.sections.map(ut.unzipSection);return{id:r.id||Me.nextId(),createdAt:r.createdAt,updatedAt:r.updatedAt,publishedAt:r.publishedAt,isPublic:r.isPublic??!0,templateConfig:r.templateConfig,slug:h,sections:Object.fromEntries(p.map(m=>[m.id,m])),sectionIds:p.map(m=>m.id),locales:Object.fromEntries(S.map(({locale:m,page:T})=>[m,T.meta])),dataSource:r.dataSource?Object.fromEntries([...new Set(S.flatMap(({page:m})=>Object.keys(m.dataSource??{})))].map(m=>[m,Object.fromEntries(S.map(({locale:T,page:M})=>{const _=M.dataSource?.[m];return[T,_||{}]}))])):Object.fromEntries([...new Set(S.flatMap(({page:m})=>m.sections.map(T=>T.id)))].map(m=>[m,Object.fromEntries(S.map(({locale:T,page:M})=>{const _=M.dataSource?.[m];if(_)return[T,_];const x=M.sections.find(Y=>Y.id===m);return[T,x?.properties||{}]}))]))}}))),P=L(await Promise.all((w?.routes||[]).map(async({path:h})=>{const S=O?await I(O,ie(h)):void 0;return{...S,id:S?.id||Me.nextId(),createdAt:S?.createdAt??new Date().toISOString(),updatedAt:S?.updatedAt??new Date().toISOString(),publishedAt:new Date(0).toISOString(),path:S?.path??`/${S?.id}`,params:S?.params,handler:S?.handler??"Pages Kit",isPublic:S?.isPublic??!0,enabledGenerate:S?.enabledGenerate??!1,displayTemplateId:S?.displayTemplateId??void 0,dataSource:S?.dataSource??{}}}))),y=b?L(await Promise.all((w.components||[]).map(async({id:h})=>d(b,h)))):[];if(e){const h=(...S)=>{u.logger.info(`[${n?f.basename(t):f.basename(f.join(t,"../../../../"))}] importAssets:`,...S)};try{h("wait image-bin api ready"),await Ct.default({resources:[`${je.getComponentWebEndpoint(u.IMAGE_BIN_NAME)}/api/sdk/uploads`],validateStatus:p=>p>=200&&p<=500}),h("image-bin api is ready");const S={},r={};h("start to upload assets"),await Promise.allSettled([xe(y,S,{getFilePath:p=>b&&f.join(b,p),onFinish:p=>{h(`upload ${p.length} component assets`)}}),xe(D,r,{getFilePath:(p,m)=>{const T=De.default(D,m.slice(0,1));return c&&f.join(c,f.dirname(T.slug),p)},onFinish:p=>{h(`upload ${p.length} page assets`)}})]),h("upload assets done"),Pe.clear(),global.gc&&global.gc()}catch(S){h("Error during asset import:",S)}}const v={};if(a){const h=i&&f.join(f.dirname(i),"../../resources/components"),S=L(await Promise.all((w.resources?.components||[]).map(async({id:r})=>d(h,r))));S.length>0&&(v.components=Object.fromEntries(S.map((r,p)=>[r.id,{index:p,component:r}])))}return{supportedLocales:w.supportedLocales,pageIds:D.map(h=>h.id),components:Object.fromEntries(y.map((h,S)=>[h.id,{index:S,data:h}])),pages:Object.fromEntries(D.map(h=>[h.id,h])),config:w.config||{},resources:v,routeIds:P.map(h=>h.id),routes:Object.fromEntries(P.map(h=>[h.id,h])),dataSourceIds:[],dataSources:{}}}finally{n&&s&&await C.rm(s,{force:!0,recursive:!0})}}async function Ae(t,e,{routes:a,mergeMode:s="byUpdateTime",deleteRoutes:n=!1,publishMode:o=void 0}={}){try{o&&u.clearPreloadComponentsCacheByMode(o)}catch(w){u.logger.error("clear preload page cache error",{error:w})}const{pages:l,pageIds:i,routeIds:c,routes:b,supportedLocales:O}=t;if(o==="production"){let w=a??[],g=null;for(const d of c??[]){const I=b?.[d];if(I?.params&&I?.params.length>0&&I?.paramsOptions&&I?.paramsOptions.length>0){const D=se.generateParamCombinations({basePath:I.path,params:I.params,routeId:I.id,paramsOptions:I.paramsOptions,currentIndex:0,currentParams:[],currentOptionIds:[],result:[]}),P=Object.fromEntries(D.map(y=>[`${d}-${y.paramOptionIds.join("-")}`,y]));g={...g||{},...P},a||(w=[...w,...D.map(y=>`${d}-${y.paramOptionIds.join("-")}`)])}else a||w.push(d)}u.logger.info("routeIds to be published: ",w);for(const d of w){let I=d;if(I.includes("-")){const[y]=I.split("-");I=y}const D=b?.[I];if(!D){const y=e.pageIds.indexOf(I);y!==-1&&n&&(e.pageIds.splice(y,1),delete e.pages[I]);for(const v of e.pageIds)v.includes(`${I}-`)&&(e.pageIds.splice(e.pageIds.indexOf(v),1),delete e.pages[v]);u.logger.info("delete main route page",I);continue}if(d.includes("-")&&!g?.[d]){const y=e.pageIds.indexOf(d);y!==-1&&n&&(e.pageIds.splice(y,1),delete e.pages[d]),u.logger.info("delete page",d);continue}if(!D.displayTemplateId){u.logger.info("no display template",d);continue}const P=l[D.displayTemplateId];if(!P){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]=he({page:P,route:D,state:t,routeId:d,routePathInfo:g?.[d]}),u.logger.info("replace page",d);else if(s==="byUpdateTime"){const y=e.pages[D.id];(!y||D.updatedAt&&D.updatedAt>y.updatedAt)&&(e.pages[d]=he({page:P,route:D,state:t,routeId:d,routePathInfo:g?.[d]}),u.logger.info("replace page by update time",d))}}else e.pageIds.push(d),e.pages[d]=he({page:P,route:D,state:t,routeId:d,routePathInfo:g?.[d]}),u.logger.info("add page",d)}if(n&&!a)for(const d of e.pageIds)w?.includes(d)||(delete e.pages[d],u.logger.info("delete page",d)),e.pageIds=[...e.pageIds].filter(I=>w?.includes(I))}else{for(const w of i){const g=l[w];if(g)if(e.pageIds.includes(g.id)){if(s==="replace")e.pages[g.id]=g;else if(s==="byUpdateTime"){const d=e.pages[g.id];(!d||g.updatedAt&&g.updatedAt>d.updatedAt)&&(e.pages[g.id]=g)}}else e.pageIds.push(g.id),e.pages[g.id]=g}for(const w of c){const g=b[w];if(g)if(e.routeIds.includes(g.id)){if(s==="replace")e.routes[g.id]=g;else if(s==="byUpdateTime"){const d=e.routes[g.id];(!d||g.updatedAt&&g.updatedAt>d.updatedAt)&&(e.routes[g.id]=g)}}else e.routeIds.push(g.id),e.routes[g.id]=g}}if(e.supportedLocales.splice(0,e.supportedLocales.length),e.supportedLocales.push(...W.default(O)),n)for(const w of Object.keys(e.components))delete e.components[w];let R=JSON.parse(JSON.stringify(t.components));R=Object.fromEntries(await Promise.all(Object.entries(R).map(async([w,g])=>{const d=await Xe(g?.data);return[w,{...g,data:d}]}))),Object.assign(e.components,R),Object.assign(e.config,JSON.parse(JSON.stringify(t.config))),Te.default(t.resources.components)||(e.resources.components=JSON.parse(JSON.stringify(t.resources.components||{})))}const Xe=u.memoizeWithFs(async t=>{if(!Te.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((n,o)=>{t?.properties&&(t.properties[n.id]={index:o,data:n})}))}catch(s){u.logger.error("getPropertiesFromCode error",{componentId:t.id,name:t.name},{error:s})}}return t},{subdir:"getPropertiesFromCode"});let ce,Z,ue,de;const Qe=()=>je.getResources({types:[{did:ve,type:Ie},{did:Rt,type:Ie}]}),Qt=async()=>{const t=Qe(),e={};for(const a of t){const n=(await ne.glob("**/.blocklet/pages/pages.config.yml",{cwd:a.path,absolute:!0}))[0],o=n&&f.join(f.dirname(n),"../../chunks");if(o&&await q(o)){const l=await C.readdir(o);for(const i of l)e[i]=f.join(o,i)}}return e};function Ze(){return ce=(async()=>{const t=Qe();Z=(await Promise.all(t.map(async a=>{const s=a.path?await Le(a.path,{importAssets:!1}):void 0;return s?{blockletId:a.did,state:s,blockletTitle:a.title}:void 0}))).filter(a=>!!a),ue=Z.reduce((a,s)=>Object.assign(a,Object.fromEntries(Object.values(s.state.pages).map(n=>n?[n?.id,{page:n,blockletId:s.blockletId}]:[]))),{});const e=Z.reduce((a,s)=>Object.assign(a,Object.fromEntries(Object.values(s.state.components).map(n=>[n.data.id,{blockletId:s.blockletId,component:n.data}]))),{});de=Object.fromEntries(await Promise.all(Object.entries(e).map(async([a,s])=>{const n=await Xe(s.component);return[a,{...s,component:n}]})))})(),ce}function et(t){const e=Oe.default(async()=>{await Ze().catch(a=>{u.logger.error("load resource states error",{error:a})}),await t?.({states:Z,pages:ue,components:de})},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(be,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(be,e)}}const tt=Symbol.for("GLOBAL_RESOURCE_STATES_LISTENER_KEY"),at=Symbol.for("GLOBAL_ENV_UPDATE_LISTENER_KEY"),pe=globalThis;pe[tt]?.();pe[tt]=et(async({pages:t,components:e})=>{const a=await j.getProjectIds();u.logger.info(`start update resource states projects(${a.length})`,a);const s=Re.default(10);await Promise.race([new Promise(n=>{setTimeout(()=>{n({})},30*1e3)}),Promise.all(a.map(n=>s(async()=>{st({projectId:n,pages:t,components:e})})))]).catch(n=>{u.logger.error("update resource states failed:",n)})});pe[at]?.();pe[at]=()=>{const t=()=>{j.pageUrlMapCache.clear(),u.logger.info("[Cache CLEAR ALL] clear all page url map cache by env update")};return E.default.events.on(E.default.Events.envUpdate,t),()=>{E.default.events.off(E.default.Events.envUpdate,t)}};j.startPeriodicCheck();process.on("beforeExit",()=>{j.stopPeriodicCheck()});process.on("SIGINT",()=>{j.stopPeriodicCheck(),process.exit(0)});process.on("SIGTERM",()=>{j.stopPeriodicCheck(),process.exit(0)});async function st({projectId:t,pages:e,components:a}){const s=j.sharedInstances[t];if(!s){u.logger.info(`projectId: ${t} not found in sharedInstances`);return}if(s.syncedStore.resources.pages=e,(await U.findByPk(t))?.useAllResources)s.syncedStore.resources.components=a;else{const l=(await ke.findAll({where:{projectId:t}})).map(c=>c.componentId),i=Object.fromEntries(Object.entries(a||{}).filter(([c])=>l.includes(c)));s.syncedStore.resources.components=i}u.logger.info(`update [${t}] resource states:`,{pages:Object.keys(s.syncedStore.resources.pages||{}).length,components:Object.keys(s.syncedStore.resources.components||{}).length})}const Se=new Map;async function nt(t){if(!Se.has(t)){const e=Oe.default(async a=>st({projectId:a,pages:ue,components:de}),3e3);Se.set(t,e)}return Se.get(t)(t)}async function Zt(){u.logger.info("trigger reload all project resource"),E.default.events.emit(be)}async function ea({ensureLoaded:t=!0}={}){return t&&(ce??=Ze(),await ce),{states:Z,pages:ue,components:de}}exports.COMPONENT_DID=ve;exports.PUBLISH_MODES=Wt;exports.Project=U;exports.RESOURCE_TYPE=Ie;exports.SITE_STATE_PATH=z;exports.STATE_MODES=Jt;exports.SiteState=j;exports.copyRecursive=$t;exports.downloadAsset=Ye;exports.downloadAssets=He;exports.fromPackage=Le;exports.getDefaultState=Ke;exports.getResourceStates=ea;exports.initPackResourceStates=et;exports.mergeState=Ae;exports.toPackage=We;exports.triggerReloadAllProjectResource=Zt;exports.updateResourceStatesByProjectId=nt;
|