UNPKG

alinea

Version:
112 lines (110 loc) 3.31 kB
import "../chunks/chunk-NZLE2WMY.js"; // src/core/Scope.ts import { Expr } from "./Expr.js"; import { getExpr, hasExpr } from "./Internal.js"; import { entries } from "./util/Objects.js"; var scopes = /* @__PURE__ */ new WeakMap(); var ENTITY_KEY = "@alinea.Entity"; var EXPR_KEY = "@alinea.Expr"; var ScopeKey = { workspace(workspace) { return `Workspace.${workspace}`; }, root(workspace, root) { return `Root.${workspace}.${root}`; }, page(workspace, root, page) { return `Page.${workspace}.${root}.${page}`; }, type(type) { return `Type.${type}`; }, field(type, field) { return `Field.${type}.${field}`; }, entry(entryId) { return `Entry.${entryId}`; } }; var Scope = class { #keys = /* @__PURE__ */ new Map(); #paths = /* @__PURE__ */ new Map(); constructor(config) { for (const [workspaceName, workspace] of entries(config.workspaces)) { this.#insert(workspace, ScopeKey.workspace(workspaceName)); for (const [rootName, root] of entries(workspace)) { this.#insert(root, ScopeKey.root(workspaceName, rootName)); for (const [pageName, page] of entries(root)) { this.#insert(page, ScopeKey.page(workspaceName, rootName, pageName)); } } } for (const [typeName, type] of entries(config.schema)) { this.#insert(type, ScopeKey.type(typeName)); for (const [fieldName, field] of entries(type)) { this.#insert(field, ScopeKey.field(typeName, fieldName)); } } } workspaceOf(root) { const path = this.#paths.get(root); if (!path) throw new Error(`Root not found in scope: ${root}`); return this.#keys.get(path[0]); } keyOf(entity) { const path = this.#paths.get(entity); if (!path) throw new Error(`Entity not found in scope: ${entity}`); return path.join("."); } locationOf(entity) { return this.#paths.get(entity)?.slice(1); } nameOf(entity) { return this.#paths.get(entity)?.at(-1); } stringify(input) { const result = JSON.stringify(input, (key, value) => { if (this.#paths.has(value)) return { [ENTITY_KEY]: this.#paths.get(value)?.join(".") }; if (value && typeof value === "object" && hasExpr(value)) return { [EXPR_KEY]: getExpr(value) }; return value; }); return result; } parse(input) { const result = JSON.parse(input, (key, value) => { if (value && typeof value === "object") { const props = Object.keys(value); if (props.length === 1) { const [key2] = props; if (key2 === ENTITY_KEY) return this.#keys.get(value[key2]); if (key2 === EXPR_KEY) return new Expr(value[key2]); } } return value; }); return result; } #insert(entity, key) { const exists = this.#paths.get(entity); const segments = key.split("."); if (exists) throw new Error( `${segments[0]} '${segments.slice(1).join(".")}' is already in use at '${exists.slice(1).join(".")}' \u2014 ${segments[0]}s must be unique` ); this.#paths.set(entity, segments); this.#keys.set(key, entity); } }; function getScope(config) { if (!scopes.has(config)) { scopes.set(config, new Scope(config)); } return scopes.get(config); } export { Scope, ScopeKey, getScope };