@_linked/server 3.12.1 → 3.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/CHANGELOG.md +72 -0
  2. package/lib/esm/backend.d.ts +23 -5
  3. package/lib/esm/backend.js +116 -25
  4. package/lib/esm/backend.js.map +1 -1
  5. package/lib/esm/shapes/LincdAPI.d.ts +1 -1
  6. package/lib/esm/shapes/LincdAPI.js +43 -7
  7. package/lib/esm/shapes/LincdAPI.js.map +1 -1
  8. package/lib/esm/shapes/LinkedServer.d.ts +59 -39
  9. package/lib/esm/shapes/LinkedServer.js +158 -93
  10. package/lib/esm/shapes/LinkedServer.js.map +1 -1
  11. package/lib/esm/shapes/quadstores/RemoteDataset.d.ts +52 -20
  12. package/lib/esm/shapes/quadstores/RemoteDataset.js +134 -32
  13. package/lib/esm/shapes/quadstores/RemoteDataset.js.map +1 -1
  14. package/lib/esm/utils/adminChannel.d.ts +23 -51
  15. package/lib/esm/utils/adminChannel.js +50 -38
  16. package/lib/esm/utils/adminChannel.js.map +1 -1
  17. package/lib/esm/utils/effectiveRoutes.d.ts +6 -0
  18. package/lib/esm/utils/effectiveRoutes.js +2 -1
  19. package/lib/esm/utils/effectiveRoutes.js.map +1 -1
  20. package/lib/esm/utils/forwardedTransactions.d.ts +46 -0
  21. package/lib/esm/utils/forwardedTransactions.js +155 -0
  22. package/lib/esm/utils/forwardedTransactions.js.map +1 -0
  23. package/lib/esm/utils/graphTargets.d.ts +42 -17
  24. package/lib/esm/utils/graphTargets.js +62 -69
  25. package/lib/esm/utils/graphTargets.js.map +1 -1
  26. package/lib/esm/utils/linkedDependencies.d.ts +53 -7
  27. package/lib/esm/utils/linkedDependencies.js +130 -12
  28. package/lib/esm/utils/linkedDependencies.js.map +1 -1
  29. package/lib/esm/utils/ontologySync.d.ts +55 -31
  30. package/lib/esm/utils/ontologySync.js +94 -42
  31. package/lib/esm/utils/ontologySync.js.map +1 -1
  32. package/lib/esm/utils/queryPlane.d.ts +13 -0
  33. package/lib/esm/utils/queryPlane.js +49 -2
  34. package/lib/esm/utils/queryPlane.js.map +1 -1
  35. package/lib/esm/utils/reloadSource.js +1 -1
  36. package/lib/esm/utils/reloadSource.js.map +1 -1
  37. package/lib/esm/utils/serverTransactions.d.ts +22 -0
  38. package/lib/esm/utils/serverTransactions.js +81 -0
  39. package/lib/esm/utils/serverTransactions.js.map +1 -0
  40. package/lib/esm/utils/syncShapes.d.ts +123 -6
  41. package/lib/esm/utils/syncShapes.js +166 -35
  42. package/lib/esm/utils/syncShapes.js.map +1 -1
  43. package/package.json +4 -4
  44. package/readme.md +158 -38
@@ -1 +1 @@
1
- {"version":3,"file":"linkedDependencies.js","sourceRoot":"","sources":["../../../src/utils/linkedDependencies.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'fs';\nimport * as path from 'path';\n\n/**\n * A linked package found in the app's dependency tree, wherever it is\n * installed: a workspace member, a localized checkout, or a registry install.\n */\nexport interface LinkedDependency {\n packageName: string;\n /**\n * Realpath of the package root whose backend the server loads: the copy the\n * app itself resolves when that copy is a linked package, otherwise the\n * first copy the walk found.\n */\n path: string;\n /**\n * Every distinct installed copy of this package in the tree (realpaths),\n * in the order the walk found them. More than one means the install is not\n * deduplicated; only `path`'s backend is ever loaded.\n */\n copies: { path: string; version?: string }[];\n}\n\n/**\n * A package whose backend providers the server loads at boot: one whose\n * package.json declares `\"linkedPackage\": true`. That flag is the only test —\n * not the package's scope. `@_linked/localize` is in the `@_linked` scope and\n * is a CLI tool, not a linked package; a custom-scope package with the flag is\n * a linked package. The CLI's workspace discovery uses the same flag.\n *\n * The legacy `\"lincd\": true` flag is deliberately NOT enough. Those packages\n * import the old `lincd` core, and loading them at boot is what produced\n * \"Multiple versions of LINCD are loaded\" before boot loading was narrowed to\n * workspace members.\n */\nexport function isLinkedPackageJson(json: any): boolean {\n if (!json || typeof json.name !== 'string') return false;\n return json.linkedPackage === true;\n}\n\n/**\n * Find an installed package the way Node does: `<dir>/node_modules/<name>`,\n * then each parent directory's `node_modules`. Returns null when it is not\n * installed (an optional dependency, say) rather than throwing.\n */\n/**\n * Whether a package has a JavaScript entry the server can import: `main`,\n * `module`, or an `exports` map with a root (`.`) entry or a single string.\n * A linked package can be pure CSS (`@_linked/css`); importing that whole\n * fails with \"Failed to resolve entry\", so the server skips it.\n */\nexport function hasModuleEntry(json: any): boolean {\n if (!json) return false;\n if (typeof json.main === 'string' || typeof json.module === 'string') {\n return true;\n }\n const exp = json.exports;\n if (typeof exp === 'string') return true;\n if (exp && typeof exp === 'object') {\n const keys = Object.keys(exp);\n // Conditions only ({import, require, ...}) describe the root entry.\n if (keys.length > 0 && keys.every((k) => !k.startsWith('.'))) return true;\n return '.' in exp;\n }\n return false;\n}\n\nexport function readInstalledPackage(\n name: string,\n fromDir: string\n): { root: string; json: any } | null {\n let dir = path.resolve(fromDir);\n while (true) {\n const root = path.join(dir, 'node_modules', name);\n const pkgJsonPath = path.join(root, 'package.json');\n if (fs.existsSync(pkgJsonPath)) {\n try {\n return { root, json: JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8')) };\n } catch {\n return null;\n }\n }\n const parent = path.dirname(dir);\n if (parent === dir) return null;\n dir = parent;\n }\n}\n\n/**\n * Every linked package reachable from the app's `dependencies`, each one AFTER\n * the linked packages it depends on. Providers register middleware in the\n * order they are indexed, so a package's middleware must not run before that\n * of a package it builds on (e.g. anything reading `request.linkedAuth` after\n * @_linked/auth's JWT middleware).\n *\n * Only linked packages are recursed into — the same rule the workspace-only\n * filter used — so the walk reads a few dozen package.json files, not the\n * whole of node_modules. Each package's dependencies are resolved from its\n * REAL location, so a symlinked workspace or localized checkout resolves its\n * own dependencies the way Node will when it loads it — which is how a\n * package installed only nested (`owl/node_modules/@_linked/rdfs`) is found.\n *\n * The walk is keyed by real path, not name, so every installed copy of a\n * package is recorded (`copies`). The copy whose backend is loaded (`path`)\n * is the one the app itself resolves, so it is the same module instance the\n * app's own imports reach; when the app cannot resolve the package at all\n * (it is only installed nested) it is the first copy found.\n */\nexport function discoverLinkedDependencies(\n appDir: string,\n appPackageJson: any\n): LinkedDependency[] {\n const out: LinkedDependency[] = [];\n const byName = new Map<string, LinkedDependency>();\n const visitedRoots = new Set<string>();\n const appName = appPackageJson?.name;\n\n const visit = (name: string, fromDir: string) => {\n if (name === appName) return;\n const installed = readInstalledPackage(name, fromDir);\n if (!installed || !isLinkedPackageJson(installed.json)) return;\n const realRoot = realpathOr(installed.root);\n if (visitedRoots.has(realRoot)) return;\n visitedRoots.add(realRoot);\n let entry = byName.get(name);\n if (!entry) {\n entry = { packageName: name, path: realRoot, copies: [] };\n byName.set(name, entry);\n }\n entry.copies.push({ path: realRoot, version: installed.json.version });\n for (const dep of Object.keys(installed.json.dependencies ?? {})) {\n visit(dep, realRoot);\n }\n // Pushed after its dependencies, once per name: the first copy found\n // fixes the package's place in the order.\n if (!out.includes(entry)) out.push(entry);\n };\n\n for (const name of Object.keys(appPackageJson?.dependencies ?? {})) {\n visit(name, appDir);\n }\n\n for (const entry of out) {\n if (entry.copies.length < 2) continue;\n const fromApp = readInstalledPackage(entry.packageName, appDir);\n if (fromApp && isLinkedPackageJson(fromApp.json)) {\n const appCopy = realpathOr(fromApp.root);\n if (entry.copies.some((c) => c.path === appCopy)) entry.path = appCopy;\n }\n }\n return out;\n}\n\n/**\n * Package name → the names of its direct `dependencies` and `peerDependencies`, for the app\n * (`appPackageJson`) and every package in `packageDirs` (name → package root, as discovery\n * found it). The shape check scopes its direction-I errors with it. A package whose\n * `package.json` cannot be read is left out.\n */\nexport function readDependencyLists(\n packageDirs: Iterable<[string, string]>,\n appPackageJson?: any\n): Record<string, string[]> {\n const lists: Record<string, string[]> = {};\n const add = (name: unknown, json: any) => {\n if (typeof name !== 'string' || !name) return;\n lists[name] = [\n ...new Set([\n ...Object.keys(json?.dependencies ?? {}),\n ...Object.keys(json?.peerDependencies ?? {}),\n ]),\n ].sort();\n };\n if (appPackageJson) add(appPackageJson.name, appPackageJson);\n for (const [name, dir] of packageDirs) {\n try {\n add(name, JSON.parse(fs.readFileSync(path.join(dir, 'package.json'), 'utf-8')));\n } catch {}\n }\n return lists;\n}\n\nfunction realpathOr(p: string): string {\n try {\n return fs.realpathSync(p);\n } catch {\n return p;\n }\n}\n\n/**\n * The conditions a backend entry is resolved with on the Node path. These are\n * the ones Node's ESM loader applies to `import()` — so the file found is the\n * file a bare `import('<pkg>/backend')` from the app would load, and Node's\n * module cache (keyed by real file URL) hands both the same instance.\n * `development` is deliberately absent: it is a Vite/bundler condition, and a\n * production Node runtime never applies it.\n */\nexport const NODE_IMPORT_CONDITIONS = ['import', 'node', 'default'] as const;\n\n/**\n * The absolute path of a package's backend entry file, or null when the\n * package has no backend entry or the file it names does not exist.\n *\n * With `exports`, this follows Node's PACKAGE_EXPORTS_RESOLVE for the\n * `./backend` subpath: an exact `./backend` key wins; otherwise the `./*`-style\n * pattern with the longest matching prefix; condition objects (nested or not)\n * pick the first key that is one of `conditions` or `default`; arrays take the\n * first target that resolves. A package that has `exports` but nothing\n * matching `./backend` has no backend — exactly as Node would refuse to\n * import it.\n *\n * Without `exports`, the legacy layout: `<root>/backend.js`,\n * `<root>/backend/index.js`, and the layout linked packages build to — a\n * `backend.js` next to `main` (`lib/esm/backend.js`).\n *\n * Hand-written rather than via `resolve.exports`: that package also stops at\n * a path and leaves the existence check to the caller, the subset needed is\n * ~50 lines, and the server keeps one less dependency in every app's install.\n */\nexport function resolveBackendEntry(\n pkgRoot: string,\n pkgJson: any,\n conditions: readonly string[] = NODE_IMPORT_CONDITIONS\n): string | null {\n const exists = (rel: string) => packageFile(pkgRoot, rel);\n const exportsField = pkgJson?.exports;\n if (exportsField === undefined || exportsField === null) {\n const candidates = ['backend.js', 'backend/index.js'];\n if (typeof pkgJson?.main === 'string') {\n candidates.push(path.join(path.dirname(pkgJson.main), 'backend.js'));\n }\n candidates.push('lib/esm/backend.js');\n for (const rel of candidates) {\n const file = exists(rel);\n if (file) return file;\n }\n return null;\n }\n return resolveBackendExport(exportsField, conditions, exists);\n}\n\n/** `<pkgRoot>/<rel>` when it is a file inside the package, else null. */\nfunction packageFile(pkgRoot: string, rel: string): string | null {\n const file = path.resolve(pkgRoot, rel);\n // Never let an export target escape the package.\n if (!file.startsWith(path.resolve(pkgRoot) + path.sep)) return null;\n try {\n return fs.statSync(file).isFile() ? file : null;\n } catch {\n return null;\n }\n}\n\n/**\n * The `./backend` subpath of an `exports` map, resolved per Node's\n * PACKAGE_EXPORTS_RESOLVE (see resolveBackendEntry). `probe` turns a matched\n * `./`-relative target into a file, or null when it does not resolve.\n */\nfunction resolveBackendExport(\n exportsField: any,\n conditions: readonly string[],\n probe: (rel: string) => string | null\n): string | null {\n // `\"exports\": \"./x.js\"`, an array, or a condition object at the top level\n // are all sugar for the \".\" subpath only.\n if (\n typeof exportsField !== 'object' ||\n Array.isArray(exportsField) ||\n !Object.keys(exportsField).some((k) => k.startsWith('.'))\n ) {\n return null;\n }\n\n const subpath = './backend';\n let target: any;\n let patternMatch: string | null = null;\n if (Object.prototype.hasOwnProperty.call(exportsField, subpath)) {\n target = exportsField[subpath];\n } else {\n let bestKey: string | null = null;\n for (const key of Object.keys(exportsField)) {\n const star = key.indexOf('*');\n if (star === -1 || key.indexOf('*', star + 1) !== -1) continue;\n const prefix = key.slice(0, star);\n const suffix = key.slice(star + 1);\n if (\n subpath !== prefix &&\n subpath.length >= key.length &&\n subpath.startsWith(prefix) &&\n subpath.endsWith(suffix) &&\n (bestKey === null || patternKeyCompare(bestKey, key) > 0)\n ) {\n bestKey = key;\n patternMatch = subpath.slice(prefix.length, subpath.length - suffix.length);\n }\n }\n if (bestKey === null) return null;\n target = exportsField[bestKey];\n }\n\n const resolveTarget = (t: any): string | null => {\n if (typeof t === 'string') {\n if (!t.startsWith('./')) return null;\n const rel = patternMatch === null ? t : t.split('*').join(patternMatch);\n return probe(rel);\n }\n if (Array.isArray(t)) {\n for (const item of t) {\n const file = resolveTarget(item);\n if (file) return file;\n }\n return null;\n }\n if (t && typeof t === 'object') {\n for (const key of Object.keys(t)) {\n if (key === 'default' || conditions.includes(key)) {\n // Node takes the first matching condition even if its target fails\n // to resolve; it does not fall through to later keys.\n return resolveTarget(t[key]);\n }\n }\n }\n return null;\n };\n return resolveTarget(target);\n}\n\n/**\n * The SOURCE file a dev Vite runner loads for `<pkg>/backend` when the\n * package is a source package — its real root has a `src/` directory, which is\n * what makes `linked`'s Vite config register it as a workspace (cli\n * `discoverWorkspaces` / `readSourcePackage`). Null when the package has no\n * `src/` or no source backend; the caller then falls back to\n * resolveBackendEntry (a built `lib/` copy, or nothing).\n *\n * Mirrors the cli's `resolveWorkspaceSpecifier` for the `./backend` subpath,\n * which runs BEFORE `exports`: `src/backend.tsx`, `src/backend.ts`, then the\n * package's own `exports` under `import`/`default` with a `./lib/esm/X.js`\n * target mapped to `src/X.tsx` / `src/X.ts` (any other `./lib/esm/` target to\n * the same path under src). So an unbuilt workspace, whose `exports` name only\n * `lib/esm`, still has its backend found, and a built one reports the src file\n * Vite actually evaluates rather than its stale `lib/`.\n *\n * Only meaningful when the dev Vite runner owns the package; Node (production,\n * external packages) loads `lib/` and never sees src.\n */\nexport function resolveSourceBackendEntry(\n pkgRoot: string,\n pkgJson: any\n): string | null {\n try {\n if (!fs.statSync(path.join(pkgRoot, 'src')).isDirectory()) return null;\n } catch {\n return null;\n }\n for (const rel of ['src/backend.tsx', 'src/backend.ts']) {\n const file = packageFile(pkgRoot, rel);\n if (file) return file;\n }\n const exportsField = pkgJson?.exports;\n if (exportsField === undefined || exportsField === null) return null;\n const libPrefix = './lib/esm/';\n return resolveBackendExport(exportsField, ['import'], (rel) => {\n if (!rel.startsWith(libPrefix)) return null;\n const sub = rel.slice(libPrefix.length);\n if (/\\.jsx?$/.test(sub)) {\n const base = 'src/' + sub.replace(/\\.jsx?$/, '');\n return packageFile(pkgRoot, base + '.tsx') ?? packageFile(pkgRoot, base + '.ts');\n }\n return packageFile(pkgRoot, 'src/' + sub);\n });\n}\n\n/** Node's PATTERN_KEY_COMPARE: < 0 means `a` is the more specific pattern. */\nfunction patternKeyCompare(a: string, b: string): number {\n const aBase = a.indexOf('*');\n const bBase = b.indexOf('*');\n const baseA = aBase === -1 ? a.length : aBase + 1;\n const baseB = bBase === -1 ? b.length : bBase + 1;\n if (baseA > baseB) return -1;\n if (baseB > baseA) return 1;\n if (aBase === -1) return 1;\n if (bBase === -1) return -1;\n if (a.length > b.length) return -1;\n if (b.length > a.length) return 1;\n return 0;\n}\n\n/**\n * Whether the dev SSR runner BUNDLES `pkgName` (it is in Vite's\n * `ssr.noExternal`) rather than handing it to Node.\n *\n * This decides which loader a package's backend must be loaded with. A module\n * has to be evaluated by the same loader that evaluates the package everywhere\n * else in the SSR graph, or it runs twice:\n *\n * - `vite.ssrLoadModule('<external pkg>/backend')` transforms that entry and\n * its relative imports even though the package is external, while the app's\n * bare imports of the same package are evaluated by Node — two copies of the\n * package's module state.\n * - a plain `import()` of a BUNDLED package goes to Node, while the app's\n * imports of it are evaluated by Vite — the same split the other way round.\n *\n * Vite matches `noExternal` entries against the bare package name, so a\n * subpath (`pkg/backend`) is covered by an entry for `pkg`.\n */\nexport function isBundledBySsr(pkgName: string, noExternal: unknown): boolean {\n if (noExternal === true) return true;\n const entries = Array.isArray(noExternal)\n ? noExternal\n : noExternal\n ? [noExternal]\n : [];\n return entries.some((entry) =>\n typeof entry === 'string'\n ? entry === pkgName\n : entry instanceof RegExp\n ? entry.test(pkgName)\n : false\n );\n}\n\n/** The dev SSR runner's resolved `noExternal`, wherever this Vite keeps it. */\nexport function ssrNoExternalOf(vite: any): unknown {\n return (\n vite?.config?.ssr?.noExternal ??\n vite?.config?.environments?.ssr?.resolve?.noExternal\n );\n}\n\n/**\n * The backend entry of a package the dev Vite runner owns (see isBundledBySsr):\n * its source backend when it is a source package (resolveSourceBackendEntry),\n * otherwise what `exports` names under the `development` condition and Node's\n * import conditions. A registry install has no src/, so it resolves exactly\n * as before.\n */\nexport function resolveDevBackendEntry(\n pkgRoot: string,\n pkgJson: any\n): string | null {\n return (\n resolveSourceBackendEntry(pkgRoot, pkgJson) ??\n resolveBackendEntry(pkgRoot, pkgJson, [\n 'development',\n ...NODE_IMPORT_CONDITIONS,\n ])\n );\n}\n"]}
1
+ {"version":3,"file":"linkedDependencies.js","sourceRoot":"","sources":["../../../src/utils/linkedDependencies.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'fs';\nimport * as path from 'path';\nimport { unpublishedPackages } from '@_linked/cli/installed-packages';\n\n/**\n * A linked package found in the app's dependency tree, wherever it is\n * installed: a workspace member, a localized checkout, or a registry install.\n */\nexport interface LinkedDependency {\n packageName: string;\n /**\n * Realpath of the package root whose backend the server loads: the copy the\n * app itself resolves when that copy is a linked package, otherwise the\n * first copy the walk found.\n */\n path: string;\n /**\n * Every distinct installed copy of this package in the tree (realpaths),\n * in the order the walk found them. More than one means the install is not\n * deduplicated; only `path`'s backend is ever loaded.\n */\n copies: { path: string; version?: string }[];\n}\n\n// linkedKind: twin of @_linked/cli src/installed-packages.ts, keep byte-identical.\n/** What a `package.json` is, by its `linked.kind`. */\nexport type LinkedKind = 'app' | 'ontology' | 'assets' | 'library';\n\n/** Every value `linked.kind` may take. */\nexport const LINKED_KINDS: readonly LinkedKind[] = [\n 'app',\n 'ontology',\n 'assets',\n 'library',\n];\n\n/**\n * THE way to tell what a `package.json` is: its `\"linked\": {\"kind\": …}`. `app` is an app (built\n * by `linked build-app`); `ontology`, `assets` and `library` are linked packages (an ontology\n * package may carry shapes for its own terms; `library` is framework code). Undefined for\n * anything else: no `linked` object and a kind that is not one of these.\n *\n * Until every published package carries `linked.kind`, a `package.json` without one is still\n * read by the retired flags: `linkedApp: true` is an `app`, `linkedPackage: true` a `library`.\n */\nexport function linkedKind(json: unknown): LinkedKind | undefined {\n if (!json || typeof json !== 'object') return undefined;\n const linked: unknown = (json as {linked?: unknown}).linked;\n if (!linked || typeof linked !== 'object') return retiredFlagKind(json);\n const kind: unknown = (linked as {kind?: unknown}).kind;\n return LINKED_KINDS.find((k) => k === kind) ?? retiredFlagKind(json);\n}\n\n/** The kind a `package.json` published before `linked.kind` declares by its retired flags. */\nfunction retiredFlagKind(json: object): LinkedKind | undefined {\n const flags = json as {linkedApp?: unknown; linkedPackage?: unknown};\n if (flags.linkedApp === true) return 'app';\n if (flags.linkedPackage === true) return 'library';\n return undefined;\n}\n// end of the linkedKind twin.\n\n/**\n * A package whose backend providers the server loads at boot: a named package\n * whose `linked.kind` is not `app` ({@link linkedKind}). That is the only test —\n * not the package's scope. `@_linked/localize` is in the `@_linked` scope and\n * is a CLI tool, not a linked package; a custom-scope package with a kind is\n * a linked package. The CLI's workspace discovery uses the same test.\n *\n * The legacy `\"lincd\": true` flag is deliberately NOT enough. Those packages\n * import the old `lincd` core, and loading them at boot is what produced\n * \"Multiple versions of LINCD are loaded\" before boot loading was narrowed to\n * workspace members.\n */\nexport function isLinkedPackageJson(json: any): boolean {\n if (!json || typeof json.name !== 'string') return false;\n const kind = linkedKind(json);\n return kind !== undefined && kind !== 'app';\n}\n\n/**\n * Find an installed package the way Node does: `<dir>/node_modules/<name>`,\n * then each parent directory's `node_modules`. Returns null when it is not\n * installed (an optional dependency, say) rather than throwing.\n */\n/**\n * Whether a package has a JavaScript entry the server can import: `main`,\n * `module`, or an `exports` map with a root (`.`) entry or a single string.\n * A linked package can be pure CSS (`@_linked/css`); importing that whole\n * fails with \"Failed to resolve entry\", so the server skips it.\n */\nexport function hasModuleEntry(json: any): boolean {\n if (!json) return false;\n if (typeof json.main === 'string' || typeof json.module === 'string') {\n return true;\n }\n const exp = json.exports;\n if (typeof exp === 'string') return true;\n if (exp && typeof exp === 'object') {\n const keys = Object.keys(exp);\n // Conditions only ({import, require, ...}) describe the root entry.\n if (keys.length > 0 && keys.every((k) => !k.startsWith('.'))) return true;\n return '.' in exp;\n }\n return false;\n}\n\nexport function readInstalledPackage(\n name: string,\n fromDir: string\n): { root: string; json: any } | null {\n let dir = path.resolve(fromDir);\n while (true) {\n const root = path.join(dir, 'node_modules', name);\n const pkgJsonPath = path.join(root, 'package.json');\n if (fs.existsSync(pkgJsonPath)) {\n try {\n return { root, json: JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8')) };\n } catch {\n return null;\n }\n }\n const parent = path.dirname(dir);\n if (parent === dir) return null;\n dir = parent;\n }\n}\n\n/**\n * The npm names a `package.json` lists in `linked.unpublishedPackages` (K-unpublished): packages\n * it uses that are not on npm, localized into the app's `packages-local/`. The server treats them\n * as direct dependencies of whoever lists them. Read with the cli's one reader, so a malformed\n * list throws rather than shrinking silently.\n */\nexport function unpublishedNames(json: unknown): string[] {\n return unpublishedPackages(json).map((p) => p.name);\n}\n\n/** Where a listed package's checkout lives in the app, when npm has not linked it yet. */\nconst LOCAL_DIR = 'packages-local';\n\n/**\n * A package the app lists in `linked.unpublishedPackages`, found by its npm name: first the\n * way Node finds it (`node_modules/<name>` from `fromDir` up, which is npm's workspace link into\n * `packages-local/` once the app is installed), else among `<appDir>/packages-local/<dir>`\n * by the `name` in each `package.json` (a checkout not yet installed). Null when there is no\n * checkout of it.\n */\nexport function findListedPackage(\n name: string,\n fromDir: string,\n appDir: string\n): { root: string; json: any } | null {\n const installed = readInstalledPackage(name, fromDir);\n if (installed) return installed;\n const localDir = path.join(appDir, LOCAL_DIR);\n let entries: string[] = [];\n try {\n entries = fs.readdirSync(localDir).sort();\n } catch {\n return null;\n }\n for (const entry of entries) {\n const root = path.join(localDir, entry);\n try {\n const json = JSON.parse(fs.readFileSync(path.join(root, 'package.json'), 'utf-8'));\n if (json?.name === name) return { root, json };\n } catch {}\n }\n return null;\n}\n\n/**\n * Every name in the app's `linked.unpublishedPackages`, and transitively in the lists of the\n * listed packages it finds ({@link findListedPackage}): the packages the server treats as the\n * app's own direct dependencies. A listed package without a checkout still counts; only its own\n * list cannot be read.\n */\nexport function listedPackageNames(appDir: string, appPackageJson: any): Set<string> {\n const names = new Set<string>();\n const queue = unpublishedNames(appPackageJson).map((name) => ({ name, fromDir: appDir }));\n while (queue.length) {\n const { name, fromDir } = queue.shift()!;\n if (names.has(name) || name === appPackageJson?.name) continue;\n names.add(name);\n const found = findListedPackage(name, fromDir, appDir);\n if (!found) continue;\n const root = realpathOr(found.root);\n for (const next of unpublishedNames(found.json)) queue.push({ name: next, fromDir: root });\n }\n return names;\n}\n\n/**\n * Every linked package reachable from the app's `dependencies` and its\n * `linked.unpublishedPackages` (transitively, through each package's own\n * `dependencies` and list), each one AFTER\n * the linked packages it depends on. Providers register middleware in the\n * order they are indexed, so a package's middleware must not run before that\n * of a package it builds on (e.g. anything reading `request.linkedAuth` after\n * @_linked/auth's JWT middleware).\n *\n * Only linked packages are recursed into — the same rule the workspace-only\n * filter used — so the walk reads a few dozen package.json files, not the\n * whole of node_modules. Each package's dependencies are resolved from its\n * REAL location, so a symlinked workspace or localized checkout resolves its\n * own dependencies the way Node will when it loads it — which is how a\n * package installed only nested (`owl/node_modules/@_linked/rdfs`) is found.\n *\n * The walk is keyed by real path, not name, so every installed copy of a\n * package is recorded (`copies`). The copy whose backend is loaded (`path`)\n * is the one the app itself resolves, so it is the same module instance the\n * app's own imports reach; when the app cannot resolve the package at all\n * (it is only installed nested) it is the first copy found.\n *\n * `isLinked` decides which installed packages are linked ones (default\n * {@link isLinkedPackageJson}); a caller reading installs of another\n * generation passes its own.\n */\nexport function discoverLinkedDependencies(\n appDir: string,\n appPackageJson: any,\n isLinked: (json: any) => boolean = isLinkedPackageJson\n): LinkedDependency[] {\n const out: LinkedDependency[] = [];\n const byName = new Map<string, LinkedDependency>();\n const visitedRoots = new Set<string>();\n const appName = appPackageJson?.name;\n\n const visit = (name: string, fromDir: string, listed = false) => {\n if (name === appName) return;\n const installed = listed\n ? findListedPackage(name, fromDir, appDir)\n : readInstalledPackage(name, fromDir);\n if (!installed || !isLinked(installed.json)) return;\n const realRoot = realpathOr(installed.root);\n if (visitedRoots.has(realRoot)) return;\n visitedRoots.add(realRoot);\n let entry = byName.get(name);\n if (!entry) {\n entry = { packageName: name, path: realRoot, copies: [] };\n byName.set(name, entry);\n }\n entry.copies.push({ path: realRoot, version: installed.json.version });\n for (const dep of Object.keys(installed.json.dependencies ?? {})) {\n visit(dep, realRoot);\n }\n for (const dep of unpublishedNames(installed.json)) {\n visit(dep, realRoot, true);\n }\n // Pushed after its dependencies, once per name: the first copy found\n // fixes the package's place in the order.\n if (!out.includes(entry)) out.push(entry);\n };\n\n for (const name of Object.keys(appPackageJson?.dependencies ?? {})) {\n visit(name, appDir);\n }\n for (const name of unpublishedNames(appPackageJson)) {\n visit(name, appDir, true);\n }\n\n for (const entry of out) {\n if (entry.copies.length < 2) continue;\n const fromApp = readInstalledPackage(entry.packageName, appDir);\n if (fromApp && isLinked(fromApp.json)) {\n const appCopy = realpathOr(fromApp.root);\n if (entry.copies.some((c) => c.path === appCopy)) entry.path = appCopy;\n }\n }\n return out;\n}\n\n/**\n * Package name → the names of its direct `dependencies`, `peerDependencies` and\n * `linked.unpublishedPackages`, for the app\n * (`appPackageJson`) and every package in `packageDirs` (name → package root, as discovery\n * found it). The shape check scopes its direction-I errors with it. A package whose\n * `package.json` cannot be read is left out.\n */\nexport function readDependencyLists(\n packageDirs: Iterable<[string, string]>,\n appPackageJson?: any\n): Record<string, string[]> {\n const lists: Record<string, string[]> = {};\n const add = (name: unknown, json: any) => {\n if (typeof name !== 'string' || !name) return;\n lists[name] = [\n ...new Set([\n ...Object.keys(json?.dependencies ?? {}),\n ...Object.keys(json?.peerDependencies ?? {}),\n ...unpublishedNames(json),\n ]),\n ].sort();\n };\n if (appPackageJson) add(appPackageJson.name, appPackageJson);\n for (const [name, dir] of packageDirs) {\n try {\n add(name, JSON.parse(fs.readFileSync(path.join(dir, 'package.json'), 'utf-8')));\n } catch {}\n }\n return lists;\n}\n\nfunction realpathOr(p: string): string {\n try {\n return fs.realpathSync(p);\n } catch {\n return p;\n }\n}\n\n/**\n * The conditions a backend entry is resolved with on the Node path. These are\n * the ones Node's ESM loader applies to `import()` — so the file found is the\n * file a bare `import('<pkg>/backend')` from the app would load, and Node's\n * module cache (keyed by real file URL) hands both the same instance.\n * `development` is deliberately absent: it is a Vite/bundler condition, and a\n * production Node runtime never applies it.\n */\nexport const NODE_IMPORT_CONDITIONS = ['import', 'node', 'default'] as const;\n\n/**\n * The absolute path of a package's backend entry file, or null when the\n * package has no backend entry or the file it names does not exist.\n *\n * With `exports`, this follows Node's PACKAGE_EXPORTS_RESOLVE for the\n * `./backend` subpath: an exact `./backend` key wins; otherwise the `./*`-style\n * pattern with the longest matching prefix; condition objects (nested or not)\n * pick the first key that is one of `conditions` or `default`; arrays take the\n * first target that resolves. A package that has `exports` but nothing\n * matching `./backend` has no backend — exactly as Node would refuse to\n * import it.\n *\n * Without `exports`, the legacy layout: `<root>/backend.js`,\n * `<root>/backend/index.js`, and the layout linked packages build to — a\n * `backend.js` next to `main` (`lib/esm/backend.js`).\n *\n * Hand-written rather than via `resolve.exports`: that package also stops at\n * a path and leaves the existence check to the caller, the subset needed is\n * ~50 lines, and the server keeps one less dependency in every app's install.\n */\nexport function resolveBackendEntry(\n pkgRoot: string,\n pkgJson: any,\n conditions: readonly string[] = NODE_IMPORT_CONDITIONS\n): string | null {\n const exists = (rel: string) => packageFile(pkgRoot, rel);\n const exportsField = pkgJson?.exports;\n if (exportsField === undefined || exportsField === null) {\n const candidates = ['backend.js', 'backend/index.js'];\n if (typeof pkgJson?.main === 'string') {\n candidates.push(path.join(path.dirname(pkgJson.main), 'backend.js'));\n }\n candidates.push('lib/esm/backend.js');\n for (const rel of candidates) {\n const file = exists(rel);\n if (file) return file;\n }\n return null;\n }\n return resolveBackendExport(exportsField, conditions, exists);\n}\n\n/** `<pkgRoot>/<rel>` when it is a file inside the package, else null. */\nfunction packageFile(pkgRoot: string, rel: string): string | null {\n const file = path.resolve(pkgRoot, rel);\n // Never let an export target escape the package.\n if (!file.startsWith(path.resolve(pkgRoot) + path.sep)) return null;\n try {\n return fs.statSync(file).isFile() ? file : null;\n } catch {\n return null;\n }\n}\n\n/**\n * The `./backend` subpath of an `exports` map, resolved per Node's\n * PACKAGE_EXPORTS_RESOLVE (see resolveBackendEntry). `probe` turns a matched\n * `./`-relative target into a file, or null when it does not resolve.\n */\nfunction resolveBackendExport(\n exportsField: any,\n conditions: readonly string[],\n probe: (rel: string) => string | null\n): string | null {\n // `\"exports\": \"./x.js\"`, an array, or a condition object at the top level\n // are all sugar for the \".\" subpath only.\n if (\n typeof exportsField !== 'object' ||\n Array.isArray(exportsField) ||\n !Object.keys(exportsField).some((k) => k.startsWith('.'))\n ) {\n return null;\n }\n\n const subpath = './backend';\n let target: any;\n let patternMatch: string | null = null;\n if (Object.prototype.hasOwnProperty.call(exportsField, subpath)) {\n target = exportsField[subpath];\n } else {\n let bestKey: string | null = null;\n for (const key of Object.keys(exportsField)) {\n const star = key.indexOf('*');\n if (star === -1 || key.indexOf('*', star + 1) !== -1) continue;\n const prefix = key.slice(0, star);\n const suffix = key.slice(star + 1);\n if (\n subpath !== prefix &&\n subpath.length >= key.length &&\n subpath.startsWith(prefix) &&\n subpath.endsWith(suffix) &&\n (bestKey === null || patternKeyCompare(bestKey, key) > 0)\n ) {\n bestKey = key;\n patternMatch = subpath.slice(prefix.length, subpath.length - suffix.length);\n }\n }\n if (bestKey === null) return null;\n target = exportsField[bestKey];\n }\n\n const resolveTarget = (t: any): string | null => {\n if (typeof t === 'string') {\n if (!t.startsWith('./')) return null;\n const rel = patternMatch === null ? t : t.split('*').join(patternMatch);\n return probe(rel);\n }\n if (Array.isArray(t)) {\n for (const item of t) {\n const file = resolveTarget(item);\n if (file) return file;\n }\n return null;\n }\n if (t && typeof t === 'object') {\n for (const key of Object.keys(t)) {\n if (key === 'default' || conditions.includes(key)) {\n // Node takes the first matching condition even if its target fails\n // to resolve; it does not fall through to later keys.\n return resolveTarget(t[key]);\n }\n }\n }\n return null;\n };\n return resolveTarget(target);\n}\n\n/**\n * The SOURCE file a dev Vite runner loads for `<pkg>/backend` when the\n * package is a source package — its real root has a `src/` directory, which is\n * what makes `linked`'s Vite config register it as a workspace (cli\n * `discoverWorkspaces` / `readSourcePackage`). Null when the package has no\n * `src/` or no source backend; the caller then falls back to\n * resolveBackendEntry (a built `lib/` copy, or nothing).\n *\n * Mirrors the cli's `resolveWorkspaceSpecifier` for the `./backend` subpath,\n * which runs BEFORE `exports`: `src/backend.tsx`, `src/backend.ts`, then the\n * package's own `exports` under `import`/`default` with a `./lib/esm/X.js`\n * target mapped to `src/X.tsx` / `src/X.ts` (any other `./lib/esm/` target to\n * the same path under src). So an unbuilt workspace, whose `exports` name only\n * `lib/esm`, still has its backend found, and a built one reports the src file\n * Vite actually evaluates rather than its stale `lib/`.\n *\n * Only meaningful when the dev Vite runner owns the package; Node (production,\n * external packages) loads `lib/` and never sees src.\n */\nexport function resolveSourceBackendEntry(\n pkgRoot: string,\n pkgJson: any\n): string | null {\n try {\n if (!fs.statSync(path.join(pkgRoot, 'src')).isDirectory()) return null;\n } catch {\n return null;\n }\n for (const rel of ['src/backend.tsx', 'src/backend.ts']) {\n const file = packageFile(pkgRoot, rel);\n if (file) return file;\n }\n const exportsField = pkgJson?.exports;\n if (exportsField === undefined || exportsField === null) return null;\n const libPrefix = './lib/esm/';\n return resolveBackendExport(exportsField, ['import'], (rel) => {\n if (!rel.startsWith(libPrefix)) return null;\n const sub = rel.slice(libPrefix.length);\n if (/\\.jsx?$/.test(sub)) {\n const base = 'src/' + sub.replace(/\\.jsx?$/, '');\n return packageFile(pkgRoot, base + '.tsx') ?? packageFile(pkgRoot, base + '.ts');\n }\n return packageFile(pkgRoot, 'src/' + sub);\n });\n}\n\n/** Node's PATTERN_KEY_COMPARE: < 0 means `a` is the more specific pattern. */\nfunction patternKeyCompare(a: string, b: string): number {\n const aBase = a.indexOf('*');\n const bBase = b.indexOf('*');\n const baseA = aBase === -1 ? a.length : aBase + 1;\n const baseB = bBase === -1 ? b.length : bBase + 1;\n if (baseA > baseB) return -1;\n if (baseB > baseA) return 1;\n if (aBase === -1) return 1;\n if (bBase === -1) return -1;\n if (a.length > b.length) return -1;\n if (b.length > a.length) return 1;\n return 0;\n}\n\n/**\n * Whether the dev SSR runner BUNDLES `pkgName` (it is in Vite's\n * `ssr.noExternal`) rather than handing it to Node.\n *\n * This decides which loader a package's backend must be loaded with. A module\n * has to be evaluated by the same loader that evaluates the package everywhere\n * else in the SSR graph, or it runs twice:\n *\n * - `vite.ssrLoadModule('<external pkg>/backend')` transforms that entry and\n * its relative imports even though the package is external, while the app's\n * bare imports of the same package are evaluated by Node — two copies of the\n * package's module state.\n * - a plain `import()` of a BUNDLED package goes to Node, while the app's\n * imports of it are evaluated by Vite — the same split the other way round.\n *\n * Vite matches `noExternal` entries against the bare package name, so a\n * subpath (`pkg/backend`) is covered by an entry for `pkg`.\n */\nexport function isBundledBySsr(pkgName: string, noExternal: unknown): boolean {\n if (noExternal === true) return true;\n const entries = Array.isArray(noExternal)\n ? noExternal\n : noExternal\n ? [noExternal]\n : [];\n return entries.some((entry) =>\n typeof entry === 'string'\n ? entry === pkgName\n : entry instanceof RegExp\n ? entry.test(pkgName)\n : false\n );\n}\n\n/** The dev SSR runner's resolved `noExternal`, wherever this Vite keeps it. */\nexport function ssrNoExternalOf(vite: any): unknown {\n return (\n vite?.config?.ssr?.noExternal ??\n vite?.config?.environments?.ssr?.resolve?.noExternal\n );\n}\n\n/**\n * The backend entry of a package the dev Vite runner owns (see isBundledBySsr):\n * its source backend when it is a source package (resolveSourceBackendEntry),\n * otherwise what `exports` names under the `development` condition and Node's\n * import conditions. A registry install has no src/, so it resolves exactly\n * as before.\n */\nexport function resolveDevBackendEntry(\n pkgRoot: string,\n pkgJson: any\n): string | null {\n return (\n resolveSourceBackendEntry(pkgRoot, pkgJson) ??\n resolveBackendEntry(pkgRoot, pkgJson, [\n 'development',\n ...NODE_IMPORT_CONDITIONS,\n ])\n );\n}\n"]}
@@ -1,9 +1,11 @@
1
1
  /**
2
- * Ontology sync and the shape check, as the server runs them before its shape sync: at boot and
3
- * when the host asks for a re-sync (`POST /admin/sync-shapes`).
2
+ * Ontology sync and the shape check, as the server runs them before its shape sync at boot. The
3
+ * registration and the shape check also run when the host reloads packages for
4
+ * `POST /admin/graph-content`.
4
5
  *
5
- * - The ontology sync (core `syncOntologies`) writes each registered package's ontology data into
6
- * its own named graph of the app's default dataset (`{package IRI}/graph/ontology`, with a
6
+ * - The ontology sync (core `syncOntologiesRouted` at boot; `syncOntologies` into one
7
+ * given dataset otherwise) writes each registered package's ontology data into its own named
8
+ * graph of every dataset the routing needs it in (`{package IRI}/graph/ontology`, with a
7
9
  * record in the graph registry that marks it as a hierarchy source), skipping a package whose
8
10
  * stored hash matches, so the store's RDFS view infers the class hierarchy. A store without
9
11
  * graph queries (it answers `unsupported-query-kind`, or has no `graphQuery`) gets core's
@@ -25,7 +27,7 @@
25
27
  * this server depends on has all of them. Kept apart from `LinkedServer` so the order and the failure handling can be tested without
26
28
  * booting a server.
27
29
  */
28
- import type { BootOrphanScope } from './syncShapes.js';
30
+ import { type BootOrphanScope, type RoutedGraphReport, type RoutedSyncReport } from './syncShapes.js';
29
31
  /** The subset of core's ontology and shape-check API this module calls. */
30
32
  export interface OntologyCore {
31
33
  syncOntologies(ds: unknown, options: {
@@ -35,8 +37,21 @@ export interface OntologyCore {
35
37
  skipped: string[];
36
38
  pruned: string[];
37
39
  target?: string;
38
- fallback?: true;
39
40
  }>;
41
+ /**
42
+ * Core's routed ontology sync (`@_linked/core/shapes/syncTargets`): every package's ontology
43
+ * graph into each dataset the routing needs it in. Optional so a test double can leave it out.
44
+ */
45
+ syncOntologiesRouted?(options: {
46
+ orphanScope: BootOrphanScope;
47
+ }): Promise<RoutedSyncReport<{
48
+ written: string[];
49
+ skipped: string[];
50
+ pruned: string[];
51
+ target?: string;
52
+ }>>;
53
+ /** Every dataset the router knows (where a routed sync may write). Optional for test doubles. */
54
+ routedDatasets?(): unknown[];
40
55
  checkShapeHierarchy(options: {
41
56
  dependencies?: Record<string, string[]>;
42
57
  }): Promise<Array<{
@@ -64,7 +79,13 @@ export interface OntologyCore {
64
79
  importModule?: (file: string) => Promise<unknown>;
65
80
  }) => Promise<string[]>;
66
81
  }
67
- /** What the ontology sync and the shape check did, as `POST /admin/sync-shapes` reports it. */
82
+ /** The shape check's findings by severity; `failed` holds the message of a check that threw. */
83
+ export interface ShapeCheckSummary {
84
+ errors: number;
85
+ warnings: number;
86
+ failed?: string;
87
+ }
88
+ /** What the ontology sync and the shape check did. */
68
89
  export interface OntologyPhaseResult {
69
90
  /**
70
91
  * Packages whose ontology graph (or, on a store without graph queries, hierarchy) was written,
@@ -76,26 +97,28 @@ export interface OntologyPhaseResult {
76
97
  skipped: string[];
77
98
  graphs?: string[];
78
99
  droppedGraphs?: string[];
100
+ /** A routed sync: the datasets it wrote into, the default one first. */
101
+ datasets?: string[];
102
+ /** A routed sync: package ontology graphs dropped from the default dataset (routing sends them elsewhere). */
103
+ prunedGraphs?: RoutedGraphReport[];
104
+ /** A routed sync: package ontology graphs left in another dataset routing no longer sends them to. */
105
+ leftovers?: RoutedGraphReport[];
79
106
  };
80
- /** The shape check's findings, counted by severity. */
81
- shapeCheck: {
82
- errors: number;
83
- warnings: number;
84
- };
85
- /** The first error the sync or the check threw; the phase went on without it. */
107
+ /**
108
+ * The shape check's findings, counted by severity, and the message of the error the check
109
+ * threw, if it did (`failed`). A thrown check is reported here and never fails the phase.
110
+ */
111
+ shapeCheck: ShapeCheckSummary;
112
+ /** The error the ontology sync threw; the phase went on without it. */
86
113
  failure?: Error;
87
114
  }
88
115
  /**
89
- * Whether the server syncs shapes (and so ontologies) into its app data: off when `linked.config`
90
- * sets `syncShapesOnBoot: false` or the environment sets `LINKED_SYNC_SHAPES_ON_BOOT=false`. One
91
- * switch for both syncs, at boot and on the host's request.
92
- */
93
- export declare function shapeSyncOn(env: Record<string, string | undefined>, configFlag: unknown): boolean;
94
- /**
95
- * Whether the boot syncs ontologies: when shape sync is on ({@link shapeSyncOn}) and the
96
- * environment does not opt out with `LINKED_SYNC_ONTOLOGIES_ON_BOOT=false`.
116
+ * Whether the boot syncs the shapes and the ontologies into app data: off only when `linked.config`
117
+ * sets `syncShapesOnBoot: false`. One switch for both syncs. It applies only to an app that writes
118
+ * its own graphs (`appWritesGraphs`, utils/graphTargets): under `LINKED_GRAPH_WRITER=host` the boot
119
+ * syncs nothing whatever it says.
97
120
  */
98
- export declare function bootSyncsOntologies(env: Record<string, string | undefined>, configFlag?: unknown): boolean;
121
+ export declare function shapeSyncOn(configFlag: unknown): boolean;
99
122
  /**
100
123
  * Import core's ontology sync, shape check, hierarchy loader and installed packages'
101
124
  * registration.
@@ -119,13 +142,20 @@ export declare function sourceModuleImporter(vite: {
119
142
  /**
120
143
  * Register the ontologies of the installed linked packages in `packageDirs` (package roots), sync
121
144
  * the registered ontologies into `ds` (when `sync` is set and there is a dataset), then run the
122
- * shape check. Never throws: a failed registration is logged and the phase goes on; a failed sync is logged and returned as `failure`, and the
123
- * check still runs; a failed check likewise. Logs one line for the sync, one summary line for
145
+ * shape check. Never throws: a failed registration is logged and the phase goes on; a failed sync
146
+ * is logged and returned as `failure`, and the check still runs; a check that throws is logged and
147
+ * returned as `shapeCheck.failed`. Logs one line for the sync, one summary line for
124
148
  * the check and one line per finding.
125
149
  */
126
- export declare function runOntologyPhase(ds: unknown, { core, sync, orphanScope, dependencies, packageDirs, importModule, log, warn, }: {
150
+ export declare function runOntologyPhase(ds: unknown, { core, sync, routed, orphanScope, dependencies, packageDirs, importModule, log, warn, }: {
127
151
  core: OntologyCore;
128
152
  sync: boolean;
153
+ /**
154
+ * Follow the routing (core's `syncOntologiesRouted`): `ds` is then the default dataset, and each
155
+ * package's graph goes to every dataset the routing needs it in. Otherwise the sync writes into
156
+ * `ds` only. The server's boot runs routed.
157
+ */
158
+ routed?: boolean;
129
159
  orphanScope: BootOrphanScope;
130
160
  dependencies?: Record<string, string[]>;
131
161
  /** Every linked package directory the server discovered (transitively). */
@@ -150,9 +180,3 @@ export declare function graphsWrittenAndDropped(ops: Array<{
150
180
  graphs: string[];
151
181
  droppedGraphs: string[];
152
182
  };
153
- /**
154
- * The host's re-sync: the ontology phase, then the shape sync, which runs also when the ontology
155
- * phase failed. The ontology phase's failure is then thrown, so the route answers with it, as
156
- * it does for a failed shape sync.
157
- */
158
- export declare function syncOntologiesThenShapes<T extends object>(ontologyPhase: () => Promise<OntologyPhaseResult>, shapeSync: () => Promise<T>): Promise<T & Pick<OntologyPhaseResult, 'ontologies' | 'shapeCheck'>>;
@@ -1,17 +1,41 @@
1
1
  /**
2
- * Whether the server syncs shapes (and so ontologies) into its app data: off when `linked.config`
3
- * sets `syncShapesOnBoot: false` or the environment sets `LINKED_SYNC_SHAPES_ON_BOOT=false`. One
4
- * switch for both syncs, at boot and on the host's request.
2
+ * Ontology sync and the shape check, as the server runs them before its shape sync at boot. The
3
+ * registration and the shape check also run when the host reloads packages for
4
+ * `POST /admin/graph-content`.
5
+ *
6
+ * - The ontology sync (core `syncOntologiesRouted` at boot; `syncOntologies` into one
7
+ * given dataset otherwise) writes each registered package's ontology data into its own named
8
+ * graph of every dataset the routing needs it in (`{package IRI}/graph/ontology`, with a
9
+ * record in the graph registry that marks it as a hierarchy source), skipping a package whose
10
+ * stored hash matches, so the store's RDFS view infers the class hierarchy. A store without
11
+ * graph queries (it answers `unsupported-query-kind`, or has no `graphQuery`) gets core's
12
+ * earlier sync of the `rdfs:subClassOf` triples into the default graph instead. The graphs the
13
+ * sync wrote or dropped are observed on core's query dispatch and reported by name.
14
+ * - The shape check (core `checkShapeHierarchy`) compares the registered shapes with that
15
+ * hierarchy. A running app is never stopped by it: its findings are logged and counted.
16
+ * - The in-memory class hierarchy (core `loadOntologyHierarchy`) is loaded also when the sync
17
+ * is off; the sync loads it itself when it runs.
18
+ * - Before either, every linked package directory the server discovered registers its ontologies
19
+ * (core `registerInstalledOntologies`): a package the app only deep-imports shape files from
20
+ * never evaluates its register modules, so its data would be missing from both. A source
21
+ * package without built register modules (a workspace package in dev) registers through
22
+ * `importModule` (Vite's `ssrLoadModule`), when the caller passes one.
23
+ *
24
+ * The four core modules (`ontology/syncOntologies`, `shapes/checkShapeHierarchy`,
25
+ * `ontology/hierarchy`, `ontology/registerInstalled`) are server only and not in core's index, so
26
+ * {@link loadOntologyCore} imports them by their fixed subpaths when the phase runs; the core
27
+ * this server depends on has all of them. Kept apart from `LinkedServer` so the order and the failure handling can be tested without
28
+ * booting a server.
5
29
  */
6
- export function shapeSyncOn(env, configFlag) {
7
- return configFlag !== false && env.LINKED_SYNC_SHAPES_ON_BOOT !== 'false';
8
- }
30
+ import { writtenAndUnchanged } from './syncShapes.js';
9
31
  /**
10
- * Whether the boot syncs ontologies: when shape sync is on ({@link shapeSyncOn}) and the
11
- * environment does not opt out with `LINKED_SYNC_ONTOLOGIES_ON_BOOT=false`.
32
+ * Whether the boot syncs the shapes and the ontologies into app data: off only when `linked.config`
33
+ * sets `syncShapesOnBoot: false`. One switch for both syncs. It applies only to an app that writes
34
+ * its own graphs (`appWritesGraphs`, utils/graphTargets): under `LINKED_GRAPH_WRITER=host` the boot
35
+ * syncs nothing whatever it says.
12
36
  */
13
- export function bootSyncsOntologies(env, configFlag) {
14
- return shapeSyncOn(env, configFlag) && env.LINKED_SYNC_ONTOLOGIES_ON_BOOT !== 'false';
37
+ export function shapeSyncOn(configFlag) {
38
+ return configFlag !== false;
15
39
  }
16
40
  /**
17
41
  * Import core's ontology sync, shape check, hierarchy loader and installed packages'
@@ -23,8 +47,12 @@ export async function loadOntologyCore() {
23
47
  const hierarchy = await import('@_linked/core/ontology/hierarchy');
24
48
  const registerInstalled = await import('@_linked/core/ontology/registerInstalled');
25
49
  const dispatch = await import('@_linked/core/queries/queryDispatch');
50
+ const targets = await import('@_linked/core/shapes/syncTargets');
51
+ const storage = await import('@_linked/core/utils/LinkedStorage');
26
52
  return {
27
53
  syncOntologies: (ds, options) => sync.syncOntologies(ds, options),
54
+ syncOntologiesRouted: (options) => targets.syncOntologiesRouted(options),
55
+ routedDatasets: () => [...storage.LinkedStorage.getDatasets()],
28
56
  checkShapeHierarchy: (options) => check.checkShapeHierarchy(options),
29
57
  loadOntologyHierarchy: () => hierarchy.loadOntologyHierarchy(),
30
58
  registerInstalledOntologies: (packageDirs, options) => registerInstalled.registerInstalledOntologies(packageDirs, options),
@@ -57,12 +85,13 @@ const list = (names) => (names.length ? names.join(', ') : 'none');
57
85
  /**
58
86
  * Register the ontologies of the installed linked packages in `packageDirs` (package roots), sync
59
87
  * the registered ontologies into `ds` (when `sync` is set and there is a dataset), then run the
60
- * shape check. Never throws: a failed registration is logged and the phase goes on; a failed sync is logged and returned as `failure`, and the
61
- * check still runs; a failed check likewise. Logs one line for the sync, one summary line for
88
+ * shape check. Never throws: a failed registration is logged and the phase goes on; a failed sync
89
+ * is logged and returned as `failure`, and the check still runs; a check that throws is logged and
90
+ * returned as `shapeCheck.failed`. Logs one line for the sync, one summary line for
62
91
  * the check and one line per finding.
63
92
  */
64
- export async function runOntologyPhase(ds, { core, sync, orphanScope, dependencies, packageDirs = [], importModule, log = console.log, warn = console.warn, }) {
65
- var _a, _b;
93
+ export async function runOntologyPhase(ds, { core, sync, routed = false, orphanScope, dependencies, packageDirs = [], importModule, log = console.log, warn = console.warn, }) {
94
+ var _a, _b, _c, _d;
66
95
  const result = {
67
96
  ontologies: { written: [], skipped: [], graphs: [], droppedGraphs: [] },
68
97
  shapeCheck: { errors: 0, warnings: 0 },
@@ -83,31 +112,64 @@ export async function runOntologyPhase(ds, { core, sync, orphanScope, dependenci
83
112
  // Every graph query that succeeded, in the order the sync sent them.
84
113
  const ops = [];
85
114
  const pending = [];
86
- const stop = (_a = core.observeGraphQueries) === null || _a === void 0 ? void 0 : _a.call(core, ds, (query, settled) => {
87
- const op = { kind: query.kind, graph: query.graph };
88
- ops.push(op);
89
- pending.push(settled.then(() => (op.ok = true), () => undefined));
115
+ if (routed && !core.syncOntologiesRouted) {
116
+ throw new Error('@_linked/core has no syncOntologiesRouted: this server needs the core it was built with');
117
+ }
118
+ const observed = routed ? (_b = (_a = core.routedDatasets) === null || _a === void 0 ? void 0 : _a.call(core)) !== null && _b !== void 0 ? _b : [ds] : [ds];
119
+ const stops = observed.map((target) => {
120
+ var _a;
121
+ return (_a = core.observeGraphQueries) === null || _a === void 0 ? void 0 : _a.call(core, target, (query, settled) => {
122
+ const op = { kind: query.kind, graph: query.graph };
123
+ ops.push(op);
124
+ pending.push(settled.then(() => (op.ok = true), () => undefined));
125
+ });
90
126
  });
127
+ const stop = () => stops.forEach((s) => s === null || s === void 0 ? void 0 : s());
91
128
  try {
92
- const sync = await core.syncOntologies(ds, { orphanScope });
129
+ let sync;
130
+ let routedRun;
131
+ if (routed) {
132
+ routedRun = await core.syncOntologiesRouted({ orphanScope });
133
+ const runs = routedRun.targets.map((t) => t.result);
134
+ const written = [...new Set(runs.flatMap((r) => r.written))].sort();
135
+ sync = {
136
+ written,
137
+ skipped: [...new Set(runs.flatMap((r) => r.skipped))].filter((n) => !written.includes(n)).sort(),
138
+ pruned: [...new Set(runs.flatMap((r) => r.pruned))].sort(),
139
+ target: (_c = runs[0]) === null || _c === void 0 ? void 0 : _c.target,
140
+ };
141
+ }
142
+ else {
143
+ sync = await core.syncOntologies(ds, { orphanScope });
144
+ }
93
145
  await Promise.all(pending);
94
146
  const { graphs, droppedGraphs } = graphsWrittenAndDropped(ops.filter((op) => op.ok));
95
147
  result.ontologies = { written: sync.written, skipped: sync.skipped, graphs, droppedGraphs };
148
+ if (routedRun) {
149
+ result.ontologies.datasets = routedRun.targets.map((t) => t.dataset);
150
+ result.ontologies.prunedGraphs = routedRun.pruned;
151
+ result.ontologies.leftovers = routedRun.leftovers;
152
+ }
96
153
  hierarchyLoaded = true;
97
- // Core ≥ 2.41 says where it wrote (the global `ontologyGraph`); an older core is told
98
- // apart by a write that sent no graph query.
154
+ // Core says where it wrote (the global `ontologyGraph`). A store without graph queries makes
155
+ // the sync throw in the 'package' and shared modes, reported below as a failed sync.
99
156
  const where = sync.target === 'default'
100
157
  ? " (default graph: ontologyGraph is 'default')"
101
- : sync.fallback || (sync.target === undefined && !!stop && sync.written.length > 0 && graphs.length === 0)
102
- ? ' (default graph: the store has no graph queries)'
103
- : sync.target && sync.target !== 'package'
104
- ? ` (one shared graph <${sync.target}>)`
105
- : '';
158
+ : sync.target && sync.target !== 'package'
159
+ ? ` (one shared graph <${sync.target}>)`
160
+ : '';
106
161
  log(`[LinkedServer] ontology sync${where}: ` +
107
- `written ${list(sync.written)}; skipped ${list(sync.skipped)}` +
162
+ writtenAndUnchanged(sync.written, sync.skipped) +
108
163
  (orphanScope === 'all' ? `; pruned ${list(sync.pruned)}` : '') +
109
164
  (graphs.length ? `; graphs written ${list(graphs)}` : '') +
110
- (droppedGraphs.length ? `; graphs dropped ${list(droppedGraphs)}` : ''));
165
+ (droppedGraphs.length ? `; graphs dropped ${list(droppedGraphs)}` : '') +
166
+ (routedRun && routedRun.targets.length > 1 ? `; datasets ${list(routedRun.targets.map((t) => t.dataset))}` : ''));
167
+ for (const { dataset, package: name, graph } of (_d = routedRun === null || routedRun === void 0 ? void 0 : routedRun.pruned) !== null && _d !== void 0 ? _d : []) {
168
+ log(`[LinkedServer] ontology sync: dropped <${graph}> (${name}) from ${dataset}: routing sends its ontology elsewhere`);
169
+ }
170
+ if (routedRun === null || routedRun === void 0 ? void 0 : routedRun.failed.length) {
171
+ throw new Error(`the ontology sync failed in ${routedRun.failed.map((f) => `${f.dataset}: ${f.error}`).join('; ')}`);
172
+ }
111
173
  }
112
174
  catch (err) {
113
175
  result.failure = asError(err);
@@ -129,12 +191,14 @@ export async function runOntologyPhase(ds, { core, sync, orphanScope, dependenci
129
191
  const findings = await core.checkShapeHierarchy({ dependencies });
130
192
  const errors = findings.filter((f) => f.severity === 'error').length;
131
193
  result.shapeCheck = { errors, warnings: findings.length - errors };
132
- log(`[LinkedServer] shape check: ${errors} error(s), ${findings.length - errors} warning(s)`);
194
+ if (findings.length) {
195
+ log(`[LinkedServer] shape check: ${errors} error(s), ${findings.length - errors} warning(s)`);
196
+ }
133
197
  for (const f of findings)
134
198
  warn(`[LinkedServer] shape check ${f.severity} (${f.kind}): ${f.message}`);
135
199
  }
136
200
  catch (err) {
137
- (_b = result.failure) !== null && _b !== void 0 ? _b : (result.failure = asError(err));
201
+ result.shapeCheck = { errors: 0, warnings: 0, failed: asError(err).message };
138
202
  warn('[LinkedServer] shape check failed:', err);
139
203
  }
140
204
  return result;
@@ -163,16 +227,4 @@ export function graphsWrittenAndDropped(ops) {
163
227
  }
164
228
  return { graphs: graphs.sort(), droppedGraphs: droppedGraphs.sort() };
165
229
  }
166
- /**
167
- * The host's re-sync: the ontology phase, then the shape sync, which runs also when the ontology
168
- * phase failed. The ontology phase's failure is then thrown, so the route answers with it, as
169
- * it does for a failed shape sync.
170
- */
171
- export async function syncOntologiesThenShapes(ontologyPhase, shapeSync) {
172
- const { ontologies, shapeCheck, failure } = await ontologyPhase();
173
- const shapes = await shapeSync();
174
- if (failure)
175
- throw failure;
176
- return { ...shapes, ontologies, shapeCheck };
177
- }
178
230
  //# sourceMappingURL=ontologySync.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ontologySync.js","sourceRoot":"","sources":["../../../src/utils/ontologySync.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Ontology sync and the shape check, as the server runs them before its shape sync: at boot and\n * when the host asks for a re-sync (`POST /admin/sync-shapes`).\n *\n * - The ontology sync (core `syncOntologies`) writes each registered package's ontology data into\n * its own named graph of the app's default dataset (`{package IRI}/graph/ontology`, with a\n * record in the graph registry that marks it as a hierarchy source), skipping a package whose\n * stored hash matches, so the store's RDFS view infers the class hierarchy. A store without\n * graph queries (it answers `unsupported-query-kind`, or has no `graphQuery`) gets core's\n * earlier sync of the `rdfs:subClassOf` triples into the default graph instead. The graphs the\n * sync wrote or dropped are observed on core's query dispatch and reported by name.\n * - The shape check (core `checkShapeHierarchy`) compares the registered shapes with that\n * hierarchy. A running app is never stopped by it: its findings are logged and counted.\n * - The in-memory class hierarchy (core `loadOntologyHierarchy`) is loaded also when the sync\n * is off; the sync loads it itself when it runs.\n * - Before either, every linked package directory the server discovered registers its ontologies\n * (core `registerInstalledOntologies`): a package the app only deep-imports shape files from\n * never evaluates its register modules, so its data would be missing from both. A source\n * package without built register modules (a workspace package in dev) registers through\n * `importModule` (Vite's `ssrLoadModule`), when the caller passes one.\n *\n * The four core modules (`ontology/syncOntologies`, `shapes/checkShapeHierarchy`,\n * `ontology/hierarchy`, `ontology/registerInstalled`) are server only and not in core's index, so\n * {@link loadOntologyCore} imports them by their fixed subpaths when the phase runs; the core\n * this server depends on has all of them. Kept apart from `LinkedServer` so the order and the failure handling can be tested without\n * booting a server.\n */\nimport type {BootOrphanScope} from './syncShapes.js';\n\n/** The subset of core's ontology and shape-check API this module calls. */\nexport interface OntologyCore {\n syncOntologies(\n ds: unknown,\n options: {orphanScope: BootOrphanScope},\n ): Promise<{written: string[]; skipped: string[]; pruned: string[]; target?: string; fallback?: true}>;\n checkShapeHierarchy(options: {dependencies?: Record<string, string[]>}): Promise<\n Array<{kind: string; severity: 'error' | 'warning'; shape?: string; iri?: string; message: string}>\n >;\n /** Loads the in-memory class hierarchy. Optional so a test double can leave it out. */\n loadOntologyHierarchy?: () => Promise<unknown>;\n /**\n * Calls `onGraph` for every graph query on `ds` that succeeds until the returned function is\n * called (core's `subscribeQueryDispatch`). Optional so a test double can leave it out.\n */\n observeGraphQueries?: (\n ds: unknown,\n onGraph: (query: {kind: string; graph: string}, settled: Promise<unknown>) => void,\n ) => () => void;\n /**\n * Registers the ontologies of the installed packages in the given directories. Optional so a\n * test double can leave it out.\n */\n registerInstalledOntologies?: (\n packageDirs: string[],\n options?: {importModule?: (file: string) => Promise<unknown>},\n ) => Promise<string[]>;\n}\n\n/** What the ontology sync and the shape check did, as `POST /admin/sync-shapes` reports it. */\nexport interface OntologyPhaseResult {\n /**\n * Packages whose ontology graph (or, on a store without graph queries, hierarchy) was written,\n * packages left as they were (unchanged or unreadable), and the graphs the sync wrote and\n * dropped (empty on a store without graph queries).\n */\n ontologies: {written: string[]; skipped: string[]; graphs?: string[]; droppedGraphs?: string[]};\n /** The shape check's findings, counted by severity. */\n shapeCheck: {errors: number; warnings: number};\n /** The first error the sync or the check threw; the phase went on without it. */\n failure?: Error;\n}\n\n/**\n * Whether the server syncs shapes (and so ontologies) into its app data: off when `linked.config`\n * sets `syncShapesOnBoot: false` or the environment sets `LINKED_SYNC_SHAPES_ON_BOOT=false`. One\n * switch for both syncs, at boot and on the host's request.\n */\nexport function shapeSyncOn(\n env: Record<string, string | undefined>,\n configFlag: unknown,\n): boolean {\n return configFlag !== false && env.LINKED_SYNC_SHAPES_ON_BOOT !== 'false';\n}\n\n/**\n * Whether the boot syncs ontologies: when shape sync is on ({@link shapeSyncOn}) and the\n * environment does not opt out with `LINKED_SYNC_ONTOLOGIES_ON_BOOT=false`.\n */\nexport function bootSyncsOntologies(\n env: Record<string, string | undefined>,\n configFlag?: unknown,\n): boolean {\n return shapeSyncOn(env, configFlag) && env.LINKED_SYNC_ONTOLOGIES_ON_BOOT !== 'false';\n}\n\n/**\n * Import core's ontology sync, shape check, hierarchy loader and installed packages'\n * registration.\n */\nexport async function loadOntologyCore(): Promise<OntologyCore> {\n const sync = await import('@_linked/core/ontology/syncOntologies');\n const check = await import('@_linked/core/shapes/checkShapeHierarchy');\n const hierarchy = await import('@_linked/core/ontology/hierarchy');\n const registerInstalled = await import('@_linked/core/ontology/registerInstalled');\n const dispatch = await import('@_linked/core/queries/queryDispatch');\n return {\n syncOntologies: (ds, options) =>\n sync.syncOntologies(ds as Parameters<typeof sync.syncOntologies>[0], options),\n checkShapeHierarchy: (options) => check.checkShapeHierarchy(options),\n loadOntologyHierarchy: () => hierarchy.loadOntologyHierarchy(),\n registerInstalledOntologies: (packageDirs, options) =>\n registerInstalled.registerInstalledOntologies(packageDirs, options),\n observeGraphQueries: (ds, onGraph) =>\n dispatch.subscribeQueryDispatch((event) => {\n if (event.kind === 'graph' && event.target === ds) onGraph(event.query, event.result);\n }),\n };\n}\n\n/**\n * The package directories whose ontologies register before the sync: every linked package\n * discovered in the app's dependency tree, then the app's own workspace packages (an ontology\n * package in `packages/` that no package imports is one, so the dependency walk never reaches it).\n * Order kept, duplicates dropped.\n */\nexport function ontologyPackageDirs(\n linkedPackageDirs: Iterable<string>,\n workspacePackageDirs: Iterable<string>,\n): string[] {\n return [...new Set([...linkedPackageDirs, ...workspacePackageDirs])];\n}\n\n/**\n * In dev, the loader for source register modules: Vite's `ssrLoadModule`, so a workspace package\n * that was never built registers on the core the SSR graph uses. Undefined without Vite (a built\n * app), where source packages are skipped.\n */\nexport function sourceModuleImporter(\n vite: {ssrLoadModule?: (url: string) => Promise<unknown>} | undefined | null,\n): ((file: string) => Promise<unknown>) | undefined {\n const ssrLoadModule = vite?.ssrLoadModule;\n return typeof ssrLoadModule === 'function' ? (file) => ssrLoadModule.call(vite, file) : undefined;\n}\n\nconst asError = (err: unknown): Error => (err instanceof Error ? err : new Error(String(err)));\nconst list = (names: string[]) => (names.length ? names.join(', ') : 'none');\n\n/**\n * Register the ontologies of the installed linked packages in `packageDirs` (package roots), sync\n * the registered ontologies into `ds` (when `sync` is set and there is a dataset), then run the\n * shape check. Never throws: a failed registration is logged and the phase goes on; a failed sync is logged and returned as `failure`, and the\n * check still runs; a failed check likewise. Logs one line for the sync, one summary line for\n * the check and one line per finding.\n */\nexport async function runOntologyPhase(\n ds: unknown,\n {\n core,\n sync,\n orphanScope,\n dependencies,\n packageDirs = [],\n importModule,\n log = console.log,\n warn = console.warn,\n }: {\n core: OntologyCore;\n sync: boolean;\n orphanScope: BootOrphanScope;\n dependencies?: Record<string, string[]>;\n /** Every linked package directory the server discovered (transitively). */\n packageDirs?: string[];\n /**\n * Imports a source register module (`src/ontologies/*.register.ts`) of a package directory\n * without built ones; in dev, Vite's `ssrLoadModule`.\n */\n importModule?: (file: string) => Promise<unknown>;\n log?: (message: string) => void;\n warn?: (message: string, err?: unknown) => void;\n },\n): Promise<OntologyPhaseResult> {\n const result: OntologyPhaseResult = {\n ontologies: {written: [], skipped: [], graphs: [], droppedGraphs: []},\n shapeCheck: {errors: 0, warnings: 0},\n };\n\n if (core.registerInstalledOntologies && packageDirs.length) {\n try {\n if (importModule) await core.registerInstalledOntologies(packageDirs, {importModule});\n else await core.registerInstalledOntologies(packageDirs);\n } catch (err) {\n warn(\"[LinkedServer] registering the installed packages' ontologies failed:\", err);\n }\n }\n\n let hierarchyLoaded = false;\n if (sync && ds) {\n // Every graph query that succeeded, in the order the sync sent them.\n const ops: Array<{kind: string; graph: string; ok?: boolean}> = [];\n const pending: Promise<unknown>[] = [];\n const stop = core.observeGraphQueries?.(ds, (query, settled) => {\n const op: {kind: string; graph: string; ok?: boolean} = {kind: query.kind, graph: query.graph};\n ops.push(op);\n pending.push(\n settled.then(\n () => (op.ok = true),\n () => undefined,\n ),\n );\n });\n try {\n const sync = await core.syncOntologies(ds, {orphanScope});\n await Promise.all(pending);\n const {graphs, droppedGraphs} = graphsWrittenAndDropped(ops.filter((op) => op.ok));\n result.ontologies = {written: sync.written, skipped: sync.skipped, graphs, droppedGraphs};\n hierarchyLoaded = true;\n // Core ≥ 2.41 says where it wrote (the global `ontologyGraph`); an older core is told\n // apart by a write that sent no graph query.\n const where =\n sync.target === 'default'\n ? \" (default graph: ontologyGraph is 'default')\"\n : sync.fallback || (sync.target === undefined && !!stop && sync.written.length > 0 && graphs.length === 0)\n ? ' (default graph: the store has no graph queries)'\n : sync.target && sync.target !== 'package'\n ? ` (one shared graph <${sync.target}>)`\n : '';\n log(\n `[LinkedServer] ontology sync${where}: ` +\n `written ${list(sync.written)}; skipped ${list(sync.skipped)}` +\n (orphanScope === 'all' ? `; pruned ${list(sync.pruned)}` : '') +\n (graphs.length ? `; graphs written ${list(graphs)}` : '') +\n (droppedGraphs.length ? `; graphs dropped ${list(droppedGraphs)}` : ''),\n );\n } catch (err) {\n result.failure = asError(err);\n warn('[LinkedServer] ontology sync failed:', err);\n } finally {\n stop?.();\n }\n }\n if (!hierarchyLoaded && core.loadOntologyHierarchy) {\n try {\n await core.loadOntologyHierarchy();\n } catch (err) {\n warn('[LinkedServer] loading the class hierarchy failed:', err);\n }\n }\n\n try {\n const findings = await core.checkShapeHierarchy({dependencies});\n const errors = findings.filter((f) => f.severity === 'error').length;\n result.shapeCheck = {errors, warnings: findings.length - errors};\n log(`[LinkedServer] shape check: ${errors} error(s), ${findings.length - errors} warning(s)`);\n for (const f of findings) warn(`[LinkedServer] shape check ${f.severity} (${f.kind}): ${f.message}`);\n } catch (err) {\n result.failure ??= asError(err);\n warn('[LinkedServer] shape check failed:', err);\n }\n return result;\n}\n\n/**\n * The graphs a sync left written and those it left dropped, from its successful graph queries in\n * order. A graph the run created and then dropped (the inference probe's temporary graphs) is in\n * neither list.\n */\nexport function graphsWrittenAndDropped(ops: Array<{kind: string; graph: string}>): {\n graphs: string[];\n droppedGraphs: string[];\n} {\n const byGraph = new Map<string, string[]>();\n for (const {kind, graph} of ops) {\n const kinds = byGraph.get(graph) ?? [];\n kinds.push(kind);\n byGraph.set(graph, kinds);\n }\n const graphs: string[] = [];\n const droppedGraphs: string[] = [];\n for (const [graph, kinds] of byGraph) {\n const last = kinds[kinds.length - 1];\n if (last !== 'graph_drop') graphs.push(graph);\n else if (kinds[0] !== 'graph_create') droppedGraphs.push(graph);\n }\n return {graphs: graphs.sort(), droppedGraphs: droppedGraphs.sort()};\n}\n\n/**\n * The host's re-sync: the ontology phase, then the shape sync, which runs also when the ontology\n * phase failed. The ontology phase's failure is then thrown, so the route answers with it, as\n * it does for a failed shape sync.\n */\nexport async function syncOntologiesThenShapes<T extends object>(\n ontologyPhase: () => Promise<OntologyPhaseResult>,\n shapeSync: () => Promise<T>,\n): Promise<T & Pick<OntologyPhaseResult, 'ontologies' | 'shapeCheck'>> {\n const {ontologies, shapeCheck, failure} = await ontologyPhase();\n const shapes = await shapeSync();\n if (failure) throw failure;\n return {...shapes, ontologies, shapeCheck};\n}\n"]}
1
+ {"version":3,"file":"ontologySync.js","sourceRoot":"","sources":["../../../src/utils/ontologySync.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Ontology sync and the shape check, as the server runs them before its shape sync at boot. The\n * registration and the shape check also run when the host reloads packages for\n * `POST /admin/graph-content`.\n *\n * - The ontology sync (core `syncOntologiesRouted` at boot; `syncOntologies` into one\n * given dataset otherwise) writes each registered package's ontology data into its own named\n * graph of every dataset the routing needs it in (`{package IRI}/graph/ontology`, with a\n * record in the graph registry that marks it as a hierarchy source), skipping a package whose\n * stored hash matches, so the store's RDFS view infers the class hierarchy. A store without\n * graph queries (it answers `unsupported-query-kind`, or has no `graphQuery`) gets core's\n * earlier sync of the `rdfs:subClassOf` triples into the default graph instead. The graphs the\n * sync wrote or dropped are observed on core's query dispatch and reported by name.\n * - The shape check (core `checkShapeHierarchy`) compares the registered shapes with that\n * hierarchy. A running app is never stopped by it: its findings are logged and counted.\n * - The in-memory class hierarchy (core `loadOntologyHierarchy`) is loaded also when the sync\n * is off; the sync loads it itself when it runs.\n * - Before either, every linked package directory the server discovered registers its ontologies\n * (core `registerInstalledOntologies`): a package the app only deep-imports shape files from\n * never evaluates its register modules, so its data would be missing from both. A source\n * package without built register modules (a workspace package in dev) registers through\n * `importModule` (Vite's `ssrLoadModule`), when the caller passes one.\n *\n * The four core modules (`ontology/syncOntologies`, `shapes/checkShapeHierarchy`,\n * `ontology/hierarchy`, `ontology/registerInstalled`) are server only and not in core's index, so\n * {@link loadOntologyCore} imports them by their fixed subpaths when the phase runs; the core\n * this server depends on has all of them. Kept apart from `LinkedServer` so the order and the failure handling can be tested without\n * booting a server.\n */\nimport {writtenAndUnchanged, type BootOrphanScope, type RoutedGraphReport, type RoutedSyncReport} from './syncShapes.js';\n\n/** The subset of core's ontology and shape-check API this module calls. */\nexport interface OntologyCore {\n syncOntologies(\n ds: unknown,\n options: {orphanScope: BootOrphanScope},\n ): Promise<{written: string[]; skipped: string[]; pruned: string[]; target?: string}>;\n /**\n * Core's routed ontology sync (`@_linked/core/shapes/syncTargets`): every package's ontology\n * graph into each dataset the routing needs it in. Optional so a test double can leave it out.\n */\n syncOntologiesRouted?(options: {orphanScope: BootOrphanScope}): Promise<\n RoutedSyncReport<{written: string[]; skipped: string[]; pruned: string[]; target?: string}>\n >;\n /** Every dataset the router knows (where a routed sync may write). Optional for test doubles. */\n routedDatasets?(): unknown[];\n checkShapeHierarchy(options: {dependencies?: Record<string, string[]>}): Promise<\n Array<{kind: string; severity: 'error' | 'warning'; shape?: string; iri?: string; message: string}>\n >;\n /** Loads the in-memory class hierarchy. Optional so a test double can leave it out. */\n loadOntologyHierarchy?: () => Promise<unknown>;\n /**\n * Calls `onGraph` for every graph query on `ds` that succeeds until the returned function is\n * called (core's `subscribeQueryDispatch`). Optional so a test double can leave it out.\n */\n observeGraphQueries?: (\n ds: unknown,\n onGraph: (query: {kind: string; graph: string}, settled: Promise<unknown>) => void,\n ) => () => void;\n /**\n * Registers the ontologies of the installed packages in the given directories. Optional so a\n * test double can leave it out.\n */\n registerInstalledOntologies?: (\n packageDirs: string[],\n options?: {importModule?: (file: string) => Promise<unknown>},\n ) => Promise<string[]>;\n}\n\n/** The shape check's findings by severity; `failed` holds the message of a check that threw. */\nexport interface ShapeCheckSummary {\n errors: number;\n warnings: number;\n failed?: string;\n}\n\n/** What the ontology sync and the shape check did. */\nexport interface OntologyPhaseResult {\n /**\n * Packages whose ontology graph (or, on a store without graph queries, hierarchy) was written,\n * packages left as they were (unchanged or unreadable), and the graphs the sync wrote and\n * dropped (empty on a store without graph queries).\n */\n ontologies: {\n written: string[];\n skipped: string[];\n graphs?: string[];\n droppedGraphs?: string[];\n /** A routed sync: the datasets it wrote into, the default one first. */\n datasets?: string[];\n /** A routed sync: package ontology graphs dropped from the default dataset (routing sends them elsewhere). */\n prunedGraphs?: RoutedGraphReport[];\n /** A routed sync: package ontology graphs left in another dataset routing no longer sends them to. */\n leftovers?: RoutedGraphReport[];\n };\n /**\n * The shape check's findings, counted by severity, and the message of the error the check\n * threw, if it did (`failed`). A thrown check is reported here and never fails the phase.\n */\n shapeCheck: ShapeCheckSummary;\n /** The error the ontology sync threw; the phase went on without it. */\n failure?: Error;\n}\n\n/**\n * Whether the boot syncs the shapes and the ontologies into app data: off only when `linked.config`\n * sets `syncShapesOnBoot: false`. One switch for both syncs. It applies only to an app that writes\n * its own graphs (`appWritesGraphs`, utils/graphTargets): under `LINKED_GRAPH_WRITER=host` the boot\n * syncs nothing whatever it says.\n */\nexport function shapeSyncOn(configFlag: unknown): boolean {\n return configFlag !== false;\n}\n\n/**\n * Import core's ontology sync, shape check, hierarchy loader and installed packages'\n * registration.\n */\nexport async function loadOntologyCore(): Promise<OntologyCore> {\n const sync = await import('@_linked/core/ontology/syncOntologies');\n const check = await import('@_linked/core/shapes/checkShapeHierarchy');\n const hierarchy = await import('@_linked/core/ontology/hierarchy');\n const registerInstalled = await import('@_linked/core/ontology/registerInstalled');\n const dispatch = await import('@_linked/core/queries/queryDispatch');\n const targets = await import('@_linked/core/shapes/syncTargets');\n const storage = await import('@_linked/core/utils/LinkedStorage');\n return {\n syncOntologies: (ds, options) =>\n sync.syncOntologies(ds as Parameters<typeof sync.syncOntologies>[0], options),\n syncOntologiesRouted: (options) => targets.syncOntologiesRouted(options),\n routedDatasets: () => [...storage.LinkedStorage.getDatasets()],\n checkShapeHierarchy: (options) => check.checkShapeHierarchy(options),\n loadOntologyHierarchy: () => hierarchy.loadOntologyHierarchy(),\n registerInstalledOntologies: (packageDirs, options) =>\n registerInstalled.registerInstalledOntologies(packageDirs, options),\n observeGraphQueries: (ds, onGraph) =>\n dispatch.subscribeQueryDispatch((event) => {\n if (event.kind === 'graph' && event.target === ds) onGraph(event.query, event.result);\n }),\n };\n}\n\n/**\n * The package directories whose ontologies register before the sync: every linked package\n * discovered in the app's dependency tree, then the app's own workspace packages (an ontology\n * package in `packages/` that no package imports is one, so the dependency walk never reaches it).\n * Order kept, duplicates dropped.\n */\nexport function ontologyPackageDirs(\n linkedPackageDirs: Iterable<string>,\n workspacePackageDirs: Iterable<string>,\n): string[] {\n return [...new Set([...linkedPackageDirs, ...workspacePackageDirs])];\n}\n\n/**\n * In dev, the loader for source register modules: Vite's `ssrLoadModule`, so a workspace package\n * that was never built registers on the core the SSR graph uses. Undefined without Vite (a built\n * app), where source packages are skipped.\n */\nexport function sourceModuleImporter(\n vite: {ssrLoadModule?: (url: string) => Promise<unknown>} | undefined | null,\n): ((file: string) => Promise<unknown>) | undefined {\n const ssrLoadModule = vite?.ssrLoadModule;\n return typeof ssrLoadModule === 'function' ? (file) => ssrLoadModule.call(vite, file) : undefined;\n}\n\nconst asError = (err: unknown): Error => (err instanceof Error ? err : new Error(String(err)));\nconst list = (names: string[]) => (names.length ? names.join(', ') : 'none');\n\n/**\n * Register the ontologies of the installed linked packages in `packageDirs` (package roots), sync\n * the registered ontologies into `ds` (when `sync` is set and there is a dataset), then run the\n * shape check. Never throws: a failed registration is logged and the phase goes on; a failed sync\n * is logged and returned as `failure`, and the check still runs; a check that throws is logged and\n * returned as `shapeCheck.failed`. Logs one line for the sync, one summary line for\n * the check and one line per finding.\n */\nexport async function runOntologyPhase(\n ds: unknown,\n {\n core,\n sync,\n routed = false,\n orphanScope,\n dependencies,\n packageDirs = [],\n importModule,\n log = console.log,\n warn = console.warn,\n }: {\n core: OntologyCore;\n sync: boolean;\n /**\n * Follow the routing (core's `syncOntologiesRouted`): `ds` is then the default dataset, and each\n * package's graph goes to every dataset the routing needs it in. Otherwise the sync writes into\n * `ds` only. The server's boot runs routed.\n */\n routed?: boolean;\n orphanScope: BootOrphanScope;\n dependencies?: Record<string, string[]>;\n /** Every linked package directory the server discovered (transitively). */\n packageDirs?: string[];\n /**\n * Imports a source register module (`src/ontologies/*.register.ts`) of a package directory\n * without built ones; in dev, Vite's `ssrLoadModule`.\n */\n importModule?: (file: string) => Promise<unknown>;\n log?: (message: string) => void;\n warn?: (message: string, err?: unknown) => void;\n },\n): Promise<OntologyPhaseResult> {\n const result: OntologyPhaseResult = {\n ontologies: {written: [], skipped: [], graphs: [], droppedGraphs: []},\n shapeCheck: {errors: 0, warnings: 0},\n };\n\n if (core.registerInstalledOntologies && packageDirs.length) {\n try {\n if (importModule) await core.registerInstalledOntologies(packageDirs, {importModule});\n else await core.registerInstalledOntologies(packageDirs);\n } catch (err) {\n warn(\"[LinkedServer] registering the installed packages' ontologies failed:\", err);\n }\n }\n\n let hierarchyLoaded = false;\n if (sync && ds) {\n // Every graph query that succeeded, in the order the sync sent them.\n const ops: Array<{kind: string; graph: string; ok?: boolean}> = [];\n const pending: Promise<unknown>[] = [];\n if (routed && !core.syncOntologiesRouted) {\n throw new Error('@_linked/core has no syncOntologiesRouted: this server needs the core it was built with');\n }\n const observed = routed ? core.routedDatasets?.() ?? [ds] : [ds];\n const stops = observed.map((target) =>\n core.observeGraphQueries?.(target, (query, settled) => {\n const op: {kind: string; graph: string; ok?: boolean} = {kind: query.kind, graph: query.graph};\n ops.push(op);\n pending.push(\n settled.then(\n () => (op.ok = true),\n () => undefined,\n ),\n );\n }),\n );\n const stop = () => stops.forEach((s) => s?.());\n try {\n let sync: {written: string[]; skipped: string[]; pruned: string[]; target?: string};\n let routedRun: RoutedSyncReport<typeof sync> | undefined;\n if (routed) {\n routedRun = await core.syncOntologiesRouted!({orphanScope});\n const runs = routedRun.targets.map((t) => t.result);\n const written = [...new Set(runs.flatMap((r) => r.written))].sort();\n sync = {\n written,\n skipped: [...new Set(runs.flatMap((r) => r.skipped))].filter((n) => !written.includes(n)).sort(),\n pruned: [...new Set(runs.flatMap((r) => r.pruned))].sort(),\n target: runs[0]?.target,\n };\n } else {\n sync = await core.syncOntologies(ds, {orphanScope});\n }\n await Promise.all(pending);\n const {graphs, droppedGraphs} = graphsWrittenAndDropped(ops.filter((op) => op.ok));\n result.ontologies = {written: sync.written, skipped: sync.skipped, graphs, droppedGraphs};\n if (routedRun) {\n result.ontologies.datasets = routedRun.targets.map((t) => t.dataset);\n result.ontologies.prunedGraphs = routedRun.pruned;\n result.ontologies.leftovers = routedRun.leftovers;\n }\n hierarchyLoaded = true;\n // Core says where it wrote (the global `ontologyGraph`). A store without graph queries makes\n // the sync throw in the 'package' and shared modes, reported below as a failed sync.\n const where =\n sync.target === 'default'\n ? \" (default graph: ontologyGraph is 'default')\"\n : sync.target && sync.target !== 'package'\n ? ` (one shared graph <${sync.target}>)`\n : '';\n log(\n `[LinkedServer] ontology sync${where}: ` +\n writtenAndUnchanged(sync.written, sync.skipped) +\n (orphanScope === 'all' ? `; pruned ${list(sync.pruned)}` : '') +\n (graphs.length ? `; graphs written ${list(graphs)}` : '') +\n (droppedGraphs.length ? `; graphs dropped ${list(droppedGraphs)}` : '') +\n (routedRun && routedRun.targets.length > 1 ? `; datasets ${list(routedRun.targets.map((t) => t.dataset))}` : ''),\n );\n for (const {dataset, package: name, graph} of routedRun?.pruned ?? []) {\n log(`[LinkedServer] ontology sync: dropped <${graph}> (${name}) from ${dataset}: routing sends its ontology elsewhere`);\n }\n if (routedRun?.failed.length) {\n throw new Error(\n `the ontology sync failed in ${routedRun.failed.map((f) => `${f.dataset}: ${f.error}`).join('; ')}`,\n );\n }\n } catch (err) {\n result.failure = asError(err);\n warn('[LinkedServer] ontology sync failed:', err);\n } finally {\n stop?.();\n }\n }\n if (!hierarchyLoaded && core.loadOntologyHierarchy) {\n try {\n await core.loadOntologyHierarchy();\n } catch (err) {\n warn('[LinkedServer] loading the class hierarchy failed:', err);\n }\n }\n\n try {\n const findings = await core.checkShapeHierarchy({dependencies});\n const errors = findings.filter((f) => f.severity === 'error').length;\n result.shapeCheck = {errors, warnings: findings.length - errors};\n if (findings.length) {\n log(`[LinkedServer] shape check: ${errors} error(s), ${findings.length - errors} warning(s)`);\n }\n for (const f of findings) warn(`[LinkedServer] shape check ${f.severity} (${f.kind}): ${f.message}`);\n } catch (err) {\n result.shapeCheck = {errors: 0, warnings: 0, failed: asError(err).message};\n warn('[LinkedServer] shape check failed:', err);\n }\n return result;\n}\n\n/**\n * The graphs a sync left written and those it left dropped, from its successful graph queries in\n * order. A graph the run created and then dropped (the inference probe's temporary graphs) is in\n * neither list.\n */\nexport function graphsWrittenAndDropped(ops: Array<{kind: string; graph: string}>): {\n graphs: string[];\n droppedGraphs: string[];\n} {\n const byGraph = new Map<string, string[]>();\n for (const {kind, graph} of ops) {\n const kinds = byGraph.get(graph) ?? [];\n kinds.push(kind);\n byGraph.set(graph, kinds);\n }\n const graphs: string[] = [];\n const droppedGraphs: string[] = [];\n for (const [graph, kinds] of byGraph) {\n const last = kinds[kinds.length - 1];\n if (last !== 'graph_drop') graphs.push(graph);\n else if (kinds[0] !== 'graph_create') droppedGraphs.push(graph);\n }\n return {graphs: graphs.sort(), droppedGraphs: droppedGraphs.sort()};\n}\n"]}