@pathmx/core 0.5.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.
- package/LICENSE.md +172 -0
- package/README.md +111 -0
- package/actions/actions.ts +307 -0
- package/actions/draft.ts +105 -0
- package/actions/transaction.ts +164 -0
- package/assets.ts +149 -0
- package/authority/access.ts +820 -0
- package/authority/actors.ts +271 -0
- package/authority/agents.ts +95 -0
- package/authority/credentials.ts +144 -0
- package/authority/model.ts +71 -0
- package/authority/sharing.ts +89 -0
- package/browser-bundle.ts +61 -0
- package/canonical.ts +41 -0
- package/cli/dev.ts +134 -0
- package/cli/export.ts +74 -0
- package/cli/index.ts +52 -0
- package/cli/lint.ts +164 -0
- package/cli/mv.ts +30 -0
- package/cli/perms.ts +182 -0
- package/cli/plugin-packages.ts +159 -0
- package/cli/plugins.ts +95 -0
- package/cli/query.ts +225 -0
- package/cli/readme.md +95 -0
- package/cli/release.ts +75 -0
- package/cli/rm.ts +22 -0
- package/cli/serve.ts +100 -0
- package/cli/tree.ts +131 -0
- package/cli/update.ts +78 -0
- package/cli/utils.ts +53 -0
- package/core.ts +96 -0
- package/database.ts +189 -0
- package/dependencies.ts +60 -0
- package/dist/pathmx.js +1224 -0
- package/document.ts +194 -0
- package/environment.ts +110 -0
- package/environments/bun-plugins.ts +68 -0
- package/environments/bun-publish.ts +194 -0
- package/environments/bun.ts +223 -0
- package/globals.d.ts +14 -0
- package/graph.ts +153 -0
- package/host/compiler.ts +314 -0
- package/host/create.ts +66 -0
- package/host/engine.ts +630 -0
- package/host/plugin-host.ts +487 -0
- package/host/render.ts +102 -0
- package/host/response.ts +20 -0
- package/host/shell.html +15 -0
- package/host/source-sync.ts +254 -0
- package/html-attributes.ts +15 -0
- package/html.ts +48 -0
- package/icons/LICENSE +43 -0
- package/icons/lucide.ts +54 -0
- package/index.ts +75 -0
- package/invalidation.ts +85 -0
- package/log.ts +84 -0
- package/ops/href.ts +87 -0
- package/ops/index.ts +9 -0
- package/ops/move-source.ts +114 -0
- package/ops/plan.ts +47 -0
- package/ops/remove-source.ts +70 -0
- package/package.json +46 -0
- package/path.ts +75 -0
- package/pattern.ts +314 -0
- package/perf.ts +88 -0
- package/plugins/actor-path.ts +43 -0
- package/plugins/actor-profile.ts +55 -0
- package/plugins/agent-browsing.ts +183 -0
- package/plugins/app-component.ts +23 -0
- package/plugins/block-layout/index.ts +78 -0
- package/plugins/block-layout/theme.css +90 -0
- package/plugins/callout/index.ts +236 -0
- package/plugins/callout/theme.css +138 -0
- package/plugins/canonical-links.ts +144 -0
- package/plugins/code-highlight/client.ts +89 -0
- package/plugins/code-highlight/index.ts +147 -0
- package/plugins/code-highlight/theme.css +89 -0
- package/plugins/context.ts +131 -0
- package/plugins/datatype/Datatype[wdth,wght].woff2 +0 -0
- package/plugins/datatype/OFL.txt +96 -0
- package/plugins/datatype/index.ts +287 -0
- package/plugins/definition-list.ts +236 -0
- package/plugins/directive-definitions.ts +13 -0
- package/plugins/embedding/client.ts +88 -0
- package/plugins/embedding/index.ts +43 -0
- package/plugins/image/index.ts +68 -0
- package/plugins/image/theme.css +43 -0
- package/plugins/include.ts +119 -0
- package/plugins/index.ts +91 -0
- package/plugins/input/authoring.ts +236 -0
- package/plugins/input/config.ts +85 -0
- package/plugins/input/index.ts +359 -0
- package/plugins/input/model.ts +173 -0
- package/plugins/input/state.ts +272 -0
- package/plugins/layout.ts +313 -0
- package/plugins/literate/client.ts +208 -0
- package/plugins/literate/index.ts +742 -0
- package/plugins/math/index.ts +140 -0
- package/plugins/meta.ts +42 -0
- package/plugins/navigation/index.ts +158 -0
- package/plugins/navigation/model.ts +364 -0
- package/plugins/preset.ts +65 -0
- package/plugins/query/index.ts +322 -0
- package/plugins/rss/index.ts +46 -0
- package/plugins/runtime/actions.ts +62 -0
- package/plugins/runtime/client.ts +8 -0
- package/plugins/runtime/document.ts +506 -0
- package/plugins/runtime/error.ts +154 -0
- package/plugins/runtime/heading-links.ts +31 -0
- package/plugins/runtime/index.ts +104 -0
- package/plugins/runtime/live.ts +51 -0
- package/plugins/runtime/navigation.ts +113 -0
- package/plugins/runtime/pending.ts +53 -0
- package/plugins/runtime/publication.ts +19 -0
- package/plugins/runtime/start.ts +177 -0
- package/plugins/runtime/static-client.ts +6 -0
- package/plugins/runtime/static-live.ts +188 -0
- package/plugins/runtime/view-transition.ts +72 -0
- package/plugins/runtime/viewport.ts +110 -0
- package/plugins/schema.ts +24 -0
- package/plugins/scripts.ts +140 -0
- package/plugins/source-preview/client.ts +256 -0
- package/plugins/source-preview/index.ts +132 -0
- package/plugins/source-preview/model.ts +11 -0
- package/plugins/source-preview/preview.css +107 -0
- package/plugins/styles.ts +145 -0
- package/plugins/theme/components.ts +10 -0
- package/plugins/theme/foundation.css +358 -0
- package/plugins/theme/index.ts +333 -0
- package/plugins/theme/prose.css +284 -0
- package/plugins/theme/scheme.js +63 -0
- package/plugins/theme/toggle.css +44 -0
- package/plugins/theme/view-transition.css +68 -0
- package/plugins/toc/client.ts +146 -0
- package/plugins/toc/index.ts +232 -0
- package/plugins/toc/theme.css +172 -0
- package/plugins/types.ts +538 -0
- package/problem.ts +41 -0
- package/project.ts +6 -0
- package/publish/build.ts +402 -0
- package/publish/concurrent.ts +32 -0
- package/publish/identity.ts +63 -0
- package/publish/index.ts +11 -0
- package/publish/location.ts +167 -0
- package/publish/model.ts +58 -0
- package/publish/plan.ts +300 -0
- package/publish/validate.ts +150 -0
- package/query/candidate-index.ts +101 -0
- package/query/dependency-index.ts +99 -0
- package/query/fields.ts +216 -0
- package/query/invalidation.ts +48 -0
- package/query/kernel.ts +776 -0
- package/query/model.ts +79 -0
- package/repository.ts +374 -0
- package/runtime-profile.ts +34 -0
- package/schema/model.ts +92 -0
- package/schema/registry.ts +642 -0
- package/schema/standard.ts +226 -0
- package/server/context.ts +94 -0
- package/server/css-imports.ts +66 -0
- package/server/http.ts +333 -0
- package/server/page.ts +21 -0
- package/server/protocols.ts +12 -0
- package/server/representations.ts +66 -0
- package/server/router.ts +131 -0
- package/server/routes.ts +202 -0
- package/server/serve.ts +5 -0
- package/server/watch.ts +120 -0
- package/source/blocks.ts +71 -0
- package/source/format.ts +164 -0
- package/source/index.ts +67 -0
- package/source/interpolate.ts +63 -0
- package/source/markdown/blocks.ts +46 -0
- package/source/markdown/comments.ts +32 -0
- package/source/markdown/fences.ts +67 -0
- package/source/markdown/headings.ts +88 -0
- package/source/markdown/index.ts +34 -0
- package/source/markdown/inline-code.ts +6 -0
- package/source/markdown/links.ts +326 -0
- package/source/markdown/lists.ts +223 -0
- package/source/markdown/prose.ts +74 -0
- package/source/markdown/scan.ts +79 -0
- package/source/markdown/text.ts +82 -0
- package/source/meta.ts +87 -0
- package/source/source.ts +121 -0
- package/source/topmatter.ts +57 -0
- package/source/utils.ts +21 -0
- package/source-diagnostic.ts +63 -0
- package/text-file.ts +26 -0
- package/util.ts +35 -0
- package/view/components.ts +499 -0
- package/view/model.ts +91 -0
- package/view/projection.ts +162 -0
- package/view/session.ts +146 -0
- package/view/syntax.ts +372 -0
package/query/fields.ts
ADDED
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import type { QueryScalar } from "./model.ts"
|
|
2
|
+
|
|
3
|
+
type JsonSchema = Readonly<Record<string, unknown>>
|
|
4
|
+
|
|
5
|
+
export type QueryField = Readonly<{
|
|
6
|
+
path: string
|
|
7
|
+
label?: string
|
|
8
|
+
description?: string
|
|
9
|
+
filterable: boolean
|
|
10
|
+
sortable: boolean
|
|
11
|
+
}>
|
|
12
|
+
|
|
13
|
+
/** @internal Read a discoverable field from a query projection or its data map. */
|
|
14
|
+
export function queryRecordValue(record: unknown, path: string): unknown {
|
|
15
|
+
const segments = path.split(".")
|
|
16
|
+
const read = (value: unknown, parts: readonly string[]) => {
|
|
17
|
+
let current = value
|
|
18
|
+
for (const segment of parts) {
|
|
19
|
+
if (current == null || typeof current !== "object") return
|
|
20
|
+
current = (current as Record<string, unknown>)[segment]
|
|
21
|
+
}
|
|
22
|
+
return current
|
|
23
|
+
}
|
|
24
|
+
const direct = read(record, segments)
|
|
25
|
+
if (direct !== undefined) return direct
|
|
26
|
+
if (segments[0] === "source") {
|
|
27
|
+
const source = read(record, ["source"])
|
|
28
|
+
const nested = read(source, segments.slice(1))
|
|
29
|
+
if (nested !== undefined) return nested
|
|
30
|
+
const sourceData = read(source, ["data"])
|
|
31
|
+
const nestedData = read(sourceData, segments.slice(1))
|
|
32
|
+
if (nestedData !== undefined) return nestedData
|
|
33
|
+
}
|
|
34
|
+
return read(read(record, ["data"]), segments)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function object(value: unknown): JsonSchema | undefined {
|
|
38
|
+
return value != null && typeof value === "object" && !Array.isArray(value)
|
|
39
|
+
? (value as JsonSchema)
|
|
40
|
+
: undefined
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function reference(root: JsonSchema, value: unknown) {
|
|
44
|
+
if (typeof value !== "string" || !value.startsWith("#/")) return
|
|
45
|
+
let current: unknown = root
|
|
46
|
+
for (const encoded of value.slice(2).split("/")) {
|
|
47
|
+
const node = object(current)
|
|
48
|
+
if (!node) return
|
|
49
|
+
const key = encoded.replaceAll("~1", "/").replaceAll("~0", "~")
|
|
50
|
+
current = node[key]
|
|
51
|
+
}
|
|
52
|
+
return object(current)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function dereference(root: JsonSchema, schema: JsonSchema) {
|
|
56
|
+
return reference(root, schema.$ref) ?? schema
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function scalarType(value: unknown) {
|
|
60
|
+
const types = Array.isArray(value) ? value : [value]
|
|
61
|
+
return (
|
|
62
|
+
types.length > 0 &&
|
|
63
|
+
types.every(
|
|
64
|
+
(type) =>
|
|
65
|
+
type === "string" ||
|
|
66
|
+
type === "number" ||
|
|
67
|
+
type === "integer" ||
|
|
68
|
+
type === "boolean" ||
|
|
69
|
+
type === "null",
|
|
70
|
+
)
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function scalarSchema(root: JsonSchema, raw: JsonSchema): boolean {
|
|
75
|
+
const schema = dereference(root, raw)
|
|
76
|
+
if (scalarType(schema.type)) return true
|
|
77
|
+
if (
|
|
78
|
+
Object.hasOwn(schema, "const") &&
|
|
79
|
+
(schema.const == null ||
|
|
80
|
+
typeof schema.const === "string" ||
|
|
81
|
+
typeof schema.const === "number" ||
|
|
82
|
+
typeof schema.const === "boolean")
|
|
83
|
+
) {
|
|
84
|
+
return true
|
|
85
|
+
}
|
|
86
|
+
if (
|
|
87
|
+
Array.isArray(schema.enum) &&
|
|
88
|
+
schema.enum.length > 0 &&
|
|
89
|
+
schema.enum.every(
|
|
90
|
+
(value) =>
|
|
91
|
+
value == null ||
|
|
92
|
+
typeof value === "string" ||
|
|
93
|
+
typeof value === "number" ||
|
|
94
|
+
typeof value === "boolean",
|
|
95
|
+
)
|
|
96
|
+
) {
|
|
97
|
+
return true
|
|
98
|
+
}
|
|
99
|
+
for (const option of [schema.anyOf, schema.oneOf]) {
|
|
100
|
+
if (
|
|
101
|
+
Array.isArray(option) &&
|
|
102
|
+
option.length > 0 &&
|
|
103
|
+
option.every((candidate) => {
|
|
104
|
+
const nested = object(candidate)
|
|
105
|
+
return nested ? scalarSchema(root, nested) : false
|
|
106
|
+
})
|
|
107
|
+
) {
|
|
108
|
+
return true
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return false
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function collect(
|
|
115
|
+
root: JsonSchema,
|
|
116
|
+
raw: JsonSchema,
|
|
117
|
+
prefix: string,
|
|
118
|
+
fields: Map<string, QueryField>,
|
|
119
|
+
) {
|
|
120
|
+
const schema = dereference(root, raw)
|
|
121
|
+
if (prefix && scalarSchema(root, schema)) {
|
|
122
|
+
fields.set(
|
|
123
|
+
prefix,
|
|
124
|
+
Object.freeze({
|
|
125
|
+
path: prefix,
|
|
126
|
+
...(typeof schema.title === "string" ? { label: schema.title } : {}),
|
|
127
|
+
...(typeof schema.description === "string"
|
|
128
|
+
? { description: schema.description }
|
|
129
|
+
: {}),
|
|
130
|
+
filterable: true,
|
|
131
|
+
sortable: true,
|
|
132
|
+
}),
|
|
133
|
+
)
|
|
134
|
+
return
|
|
135
|
+
}
|
|
136
|
+
const properties = object(schema.properties)
|
|
137
|
+
if (properties) {
|
|
138
|
+
for (const [name, candidate] of Object.entries(properties)) {
|
|
139
|
+
const nested = object(candidate)
|
|
140
|
+
if (!nested) continue
|
|
141
|
+
collect(root, nested, prefix ? `${prefix}.${name}` : name, fields)
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
if (Array.isArray(schema.allOf)) {
|
|
145
|
+
for (const candidate of schema.allOf) {
|
|
146
|
+
const nested = object(candidate)
|
|
147
|
+
if (nested) collect(root, nested, prefix, fields)
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export class QueryFieldCatalog {
|
|
153
|
+
private fields = new Map<string, QueryField>()
|
|
154
|
+
|
|
155
|
+
add(path: string, label?: string) {
|
|
156
|
+
this.fields.set(
|
|
157
|
+
path,
|
|
158
|
+
Object.freeze({
|
|
159
|
+
path,
|
|
160
|
+
...(label ? { label } : {}),
|
|
161
|
+
filterable: true,
|
|
162
|
+
sortable: true,
|
|
163
|
+
}),
|
|
164
|
+
)
|
|
165
|
+
return this
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
addObjectSchema(schema: JsonSchema, prefix = "") {
|
|
169
|
+
collect(schema, schema, prefix, this.fields)
|
|
170
|
+
return this
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
addArrayOutput(schema: JsonSchema) {
|
|
174
|
+
const root = dereference(schema, schema)
|
|
175
|
+
const type = root.type
|
|
176
|
+
if (type !== "array" && !(Array.isArray(type) && type.includes("array"))) {
|
|
177
|
+
throw new Error("Query output JSON Schema must describe an array.")
|
|
178
|
+
}
|
|
179
|
+
const items = object(root.items)
|
|
180
|
+
if (!items) {
|
|
181
|
+
throw new Error("Query output JSON Schema must describe array items.")
|
|
182
|
+
}
|
|
183
|
+
collect(schema, items, "", this.fields)
|
|
184
|
+
return this
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
has(path: string) {
|
|
188
|
+
return this.fields.has(path)
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
require(path: string, operation: "filter" | "sort") {
|
|
192
|
+
const field = this.fields.get(path)
|
|
193
|
+
const supported =
|
|
194
|
+
operation === "filter" ? field?.filterable : field?.sortable
|
|
195
|
+
if (!supported) {
|
|
196
|
+
throw new Error(`Field ${path} does not support query ${operation}.`)
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
list() {
|
|
201
|
+
return Object.freeze(
|
|
202
|
+
[...this.fields.values()].sort((left, right) =>
|
|
203
|
+
left.path.localeCompare(right.path),
|
|
204
|
+
),
|
|
205
|
+
)
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export function queryScalar(value: unknown): value is QueryScalar {
|
|
210
|
+
return (
|
|
211
|
+
value == null ||
|
|
212
|
+
typeof value === "string" ||
|
|
213
|
+
(typeof value === "number" && Number.isFinite(value)) ||
|
|
214
|
+
typeof value === "boolean"
|
|
215
|
+
)
|
|
216
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { Dependency } from "../dependencies.ts"
|
|
2
|
+
import type { Engine } from "../host/engine.ts"
|
|
3
|
+
import type { RouteInvalidations } from "../invalidation.ts"
|
|
4
|
+
import { queryDependency } from "./kernel.ts"
|
|
5
|
+
import type { Source } from "../source/index.ts"
|
|
6
|
+
|
|
7
|
+
type QueryInvalidation = Readonly<{
|
|
8
|
+
key: string
|
|
9
|
+
actors?: readonly string[]
|
|
10
|
+
}>
|
|
11
|
+
|
|
12
|
+
function addRoutes(
|
|
13
|
+
engine: Engine,
|
|
14
|
+
routes: RouteInvalidations,
|
|
15
|
+
queries: Iterable<QueryInvalidation>,
|
|
16
|
+
) {
|
|
17
|
+
for (const query of queries) {
|
|
18
|
+
for (const pagePath of engine.dependentsOf(queryDependency(query))) {
|
|
19
|
+
const page = engine.pageCache.get(pagePath)
|
|
20
|
+
if (!page) continue
|
|
21
|
+
if (query.actors) routes.addActors(page.route, query.actors)
|
|
22
|
+
else routes.add(page.route)
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** @internal Map derived query invalidation back onto compiled route consumers. */
|
|
28
|
+
export function dependencies(
|
|
29
|
+
engine: Engine,
|
|
30
|
+
routes: RouteInvalidations,
|
|
31
|
+
dependencies: Iterable<Dependency>,
|
|
32
|
+
) {
|
|
33
|
+
addRoutes(engine, routes, engine.queries.invalidateDependencies(dependencies))
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** @internal Invalidate one canonical Source transition and its derived routes. */
|
|
37
|
+
export function source(
|
|
38
|
+
engine: Engine,
|
|
39
|
+
routes: RouteInvalidations,
|
|
40
|
+
before: Source | undefined,
|
|
41
|
+
after: Source | undefined,
|
|
42
|
+
path: string,
|
|
43
|
+
) {
|
|
44
|
+
addRoutes(engine, routes, [
|
|
45
|
+
...engine.queries.transition(before, after),
|
|
46
|
+
...engine.queries.invalidateDependencies([{ type: "source", path }]),
|
|
47
|
+
])
|
|
48
|
+
}
|