@graview/core 0.1.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 +96 -0
- package/README.md +35 -0
- package/dist/app.d.ts +294 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +49 -0
- package/dist/app.js.map +1 -0
- package/dist/arrange.d.ts +185 -0
- package/dist/arrange.d.ts.map +1 -0
- package/dist/arrange.js +456 -0
- package/dist/arrange.js.map +1 -0
- package/dist/beginning.d.ts +65 -0
- package/dist/beginning.d.ts.map +1 -0
- package/dist/beginning.js +94 -0
- package/dist/beginning.js.map +1 -0
- package/dist/bind.d.ts +42 -0
- package/dist/bind.d.ts.map +1 -0
- package/dist/bind.js +26 -0
- package/dist/bind.js.map +1 -0
- package/dist/city.d.ts +93 -0
- package/dist/city.d.ts.map +1 -0
- package/dist/city.js +160 -0
- package/dist/city.js.map +1 -0
- package/dist/cli/check/arrangement.d.ts +13 -0
- package/dist/cli/check/arrangement.d.ts.map +1 -0
- package/dist/cli/check/arrangement.js +63 -0
- package/dist/cli/check/arrangement.js.map +1 -0
- package/dist/cli/check/beginnings.d.ts +16 -0
- package/dist/cli/check/beginnings.d.ts.map +1 -0
- package/dist/cli/check/beginnings.js +53 -0
- package/dist/cli/check/beginnings.js.map +1 -0
- package/dist/cli/check/brand.d.ts +17 -0
- package/dist/cli/check/brand.d.ts.map +1 -0
- package/dist/cli/check/brand.js +153 -0
- package/dist/cli/check/brand.js.map +1 -0
- package/dist/cli/check/city.d.ts +17 -0
- package/dist/cli/check/city.d.ts.map +1 -0
- package/dist/cli/check/city.js +58 -0
- package/dist/cli/check/city.js.map +1 -0
- package/dist/cli/check/context.d.ts +50 -0
- package/dist/cli/check/context.d.ts.map +1 -0
- package/dist/cli/check/context.js +37 -0
- package/dist/cli/check/context.js.map +1 -0
- package/dist/cli/check/fields.d.ts +16 -0
- package/dist/cli/check/fields.d.ts.map +1 -0
- package/dist/cli/check/fields.js +237 -0
- package/dist/cli/check/fields.js.map +1 -0
- package/dist/cli/check/index.d.ts +14 -0
- package/dist/cli/check/index.d.ts.map +1 -0
- package/dist/cli/check/index.js +14 -0
- package/dist/cli/check/index.js.map +1 -0
- package/dist/cli/check/intelligence.d.ts +17 -0
- package/dist/cli/check/intelligence.d.ts.map +1 -0
- package/dist/cli/check/intelligence.js +136 -0
- package/dist/cli/check/intelligence.js.map +1 -0
- package/dist/cli/check/lenses.d.ts +17 -0
- package/dist/cli/check/lenses.d.ts.map +1 -0
- package/dist/cli/check/lenses.js +239 -0
- package/dist/cli/check/lenses.js.map +1 -0
- package/dist/cli/check/migrations.d.ts +16 -0
- package/dist/cli/check/migrations.d.ts.map +1 -0
- package/dist/cli/check/migrations.js +43 -0
- package/dist/cli/check/migrations.js.map +1 -0
- package/dist/cli/check/modules.d.ts +16 -0
- package/dist/cli/check/modules.d.ts.map +1 -0
- package/dist/cli/check/modules.js +123 -0
- package/dist/cli/check/modules.js.map +1 -0
- package/dist/cli/check/policy.d.ts +16 -0
- package/dist/cli/check/policy.d.ts.map +1 -0
- package/dist/cli/check/policy.js +90 -0
- package/dist/cli/check/policy.js.map +1 -0
- package/dist/cli/check/relations.d.ts +29 -0
- package/dist/cli/check/relations.d.ts.map +1 -0
- package/dist/cli/check/relations.js +279 -0
- package/dist/cli/check/relations.js.map +1 -0
- package/dist/cli/check/routes.d.ts +16 -0
- package/dist/cli/check/routes.d.ts.map +1 -0
- package/dist/cli/check/routes.js +31 -0
- package/dist/cli/check/routes.js.map +1 -0
- package/dist/cli/check/settings.d.ts +16 -0
- package/dist/cli/check/settings.d.ts.map +1 -0
- package/dist/cli/check/settings.js +81 -0
- package/dist/cli/check/settings.js.map +1 -0
- package/dist/cli/check.d.ts +36 -0
- package/dist/cli/check.d.ts.map +1 -0
- package/dist/cli/check.js +76 -0
- package/dist/cli/check.js.map +1 -0
- package/dist/cli/create.d.ts +20 -0
- package/dist/cli/create.d.ts.map +1 -0
- package/dist/cli/create.js +251 -0
- package/dist/cli/create.js.map +1 -0
- package/dist/cli/describe.d.ts +35 -0
- package/dist/cli/describe.d.ts.map +1 -0
- package/dist/cli/describe.js +230 -0
- package/dist/cli/describe.js.map +1 -0
- package/dist/cli/docs.d.ts +11 -0
- package/dist/cli/docs.d.ts.map +1 -0
- package/dist/cli/docs.js +152 -0
- package/dist/cli/docs.js.map +1 -0
- package/dist/cli/index.d.ts +18 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +281 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/extend.d.ts +23 -0
- package/dist/extend.d.ts.map +1 -0
- package/dist/extend.js +53 -0
- package/dist/extend.js.map +1 -0
- package/dist/graph/diff.d.ts +31 -0
- package/dist/graph/diff.d.ts.map +1 -0
- package/dist/graph/diff.js +71 -0
- package/dist/graph/diff.js.map +1 -0
- package/dist/graph/graph.d.ts +69 -0
- package/dist/graph/graph.d.ts.map +1 -0
- package/dist/graph/graph.js +284 -0
- package/dist/graph/graph.js.map +1 -0
- package/dist/graph/primitives.d.ts +52 -0
- package/dist/graph/primitives.d.ts.map +1 -0
- package/dist/graph/primitives.js +62 -0
- package/dist/graph/primitives.js.map +1 -0
- package/dist/graph/tracked.d.ts +31 -0
- package/dist/graph/tracked.d.ts.map +1 -0
- package/dist/graph/tracked.js +69 -0
- package/dist/graph/tracked.js.map +1 -0
- package/dist/graph/types.d.ts +34 -0
- package/dist/graph/types.d.ts.map +1 -0
- package/dist/graph/types.js +0 -0
- package/dist/graph/types.js.map +1 -0
- package/dist/index.d.ts +100 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +90 -0
- package/dist/index.js.map +1 -0
- package/dist/installation.d.ts +112 -0
- package/dist/installation.d.ts.map +1 -0
- package/dist/installation.js +193 -0
- package/dist/installation.js.map +1 -0
- package/dist/intelligence-bridge.d.ts +73 -0
- package/dist/intelligence-bridge.d.ts.map +1 -0
- package/dist/intelligence-bridge.js +31 -0
- package/dist/intelligence-bridge.js.map +1 -0
- package/dist/invariants/engine.d.ts +36 -0
- package/dist/invariants/engine.d.ts.map +1 -0
- package/dist/invariants/engine.js +88 -0
- package/dist/invariants/engine.js.map +1 -0
- package/dist/invariants/types.d.ts +75 -0
- package/dist/invariants/types.d.ts.map +1 -0
- package/dist/invariants/types.js +2 -0
- package/dist/invariants/types.js.map +1 -0
- package/dist/modules.d.ts +75 -0
- package/dist/modules.d.ts.map +1 -0
- package/dist/modules.js +87 -0
- package/dist/modules.js.map +1 -0
- package/dist/mutations/decidable.d.ts +26 -0
- package/dist/mutations/decidable.d.ts.map +1 -0
- package/dist/mutations/decidable.js +39 -0
- package/dist/mutations/decidable.js.map +1 -0
- package/dist/mutations/define-mutation.d.ts +32 -0
- package/dist/mutations/define-mutation.d.ts.map +1 -0
- package/dist/mutations/define-mutation.js +181 -0
- package/dist/mutations/define-mutation.js.map +1 -0
- package/dist/mutations/derive-edits.d.ts +75 -0
- package/dist/mutations/derive-edits.d.ts.map +1 -0
- package/dist/mutations/derive-edits.js +240 -0
- package/dist/mutations/derive-edits.js.map +1 -0
- package/dist/mutations/form.d.ts +63 -0
- package/dist/mutations/form.d.ts.map +1 -0
- package/dist/mutations/form.js +113 -0
- package/dist/mutations/form.js.map +1 -0
- package/dist/mutations/node-ref.d.ts +83 -0
- package/dist/mutations/node-ref.d.ts.map +1 -0
- package/dist/mutations/node-ref.js +113 -0
- package/dist/mutations/node-ref.js.map +1 -0
- package/dist/mutations/types.d.ts +136 -0
- package/dist/mutations/types.d.ts.map +1 -0
- package/dist/mutations/types.js +2 -0
- package/dist/mutations/types.js.map +1 -0
- package/dist/ops/log.d.ts +35 -0
- package/dist/ops/log.d.ts.map +1 -0
- package/dist/ops/log.js +103 -0
- package/dist/ops/log.js.map +1 -0
- package/dist/ops/types.d.ts +52 -0
- package/dist/ops/types.d.ts.map +1 -0
- package/dist/ops/types.js +2 -0
- package/dist/ops/types.js.map +1 -0
- package/dist/ops/undo.d.ts +33 -0
- package/dist/ops/undo.d.ts.map +1 -0
- package/dist/ops/undo.js +65 -0
- package/dist/ops/undo.js.map +1 -0
- package/dist/permissions/policy.d.ts +68 -0
- package/dist/permissions/policy.d.ts.map +1 -0
- package/dist/permissions/policy.js +191 -0
- package/dist/permissions/policy.js.map +1 -0
- package/dist/permissions/types.d.ts +78 -0
- package/dist/permissions/types.d.ts.map +1 -0
- package/dist/permissions/types.js +17 -0
- package/dist/permissions/types.js.map +1 -0
- package/dist/persistence/memory.d.ts +6 -0
- package/dist/persistence/memory.d.ts.map +1 -0
- package/dist/persistence/memory.js +31 -0
- package/dist/persistence/memory.js.map +1 -0
- package/dist/persistence/sqlite.d.ts +59 -0
- package/dist/persistence/sqlite.d.ts.map +1 -0
- package/dist/persistence/sqlite.js +131 -0
- package/dist/persistence/sqlite.js.map +1 -0
- package/dist/persistence/types.d.ts +22 -0
- package/dist/persistence/types.d.ts.map +1 -0
- package/dist/persistence/types.js +2 -0
- package/dist/persistence/types.js.map +1 -0
- package/dist/presence.d.ts +38 -0
- package/dist/presence.d.ts.map +1 -0
- package/dist/presence.js +50 -0
- package/dist/presence.js.map +1 -0
- package/dist/scaffold/domain.d.ts +8 -0
- package/dist/scaffold/domain.d.ts.map +1 -0
- package/dist/scaffold/domain.js +331 -0
- package/dist/scaffold/domain.js.map +1 -0
- package/dist/scaffold/index.d.ts +66 -0
- package/dist/scaffold/index.d.ts.map +1 -0
- package/dist/scaffold/index.js +142 -0
- package/dist/scaffold/index.js.map +1 -0
- package/dist/scaffold/lens.d.ts +31 -0
- package/dist/scaffold/lens.d.ts.map +1 -0
- package/dist/scaffold/lens.js +176 -0
- package/dist/scaffold/lens.js.map +1 -0
- package/dist/scaffold/names.d.ts +44 -0
- package/dist/scaffold/names.d.ts.map +1 -0
- package/dist/scaffold/names.js +69 -0
- package/dist/scaffold/names.js.map +1 -0
- package/dist/scaffold/project.d.ts +41 -0
- package/dist/scaffold/project.d.ts.map +1 -0
- package/dist/scaffold/project.js +604 -0
- package/dist/scaffold/project.js.map +1 -0
- package/dist/scaffold/ui.d.ts +15 -0
- package/dist/scaffold/ui.d.ts.map +1 -0
- package/dist/scaffold/ui.js +536 -0
- package/dist/scaffold/ui.js.map +1 -0
- package/dist/schema/define-node.d.ts +132 -0
- package/dist/schema/define-node.d.ts.map +1 -0
- package/dist/schema/define-node.js +254 -0
- package/dist/schema/define-node.js.map +1 -0
- package/dist/schema/figures.d.ts +42 -0
- package/dist/schema/figures.d.ts.map +1 -0
- package/dist/schema/figures.js +220 -0
- package/dist/schema/figures.js.map +1 -0
- package/dist/schema/json-schema.d.ts +39 -0
- package/dist/schema/json-schema.d.ts.map +1 -0
- package/dist/schema/json-schema.js +74 -0
- package/dist/schema/json-schema.js.map +1 -0
- package/dist/schema/schema.d.ts +43 -0
- package/dist/schema/schema.d.ts.map +1 -0
- package/dist/schema/schema.js +102 -0
- package/dist/schema/schema.js.map +1 -0
- package/dist/schema/types.d.ts +201 -0
- package/dist/schema/types.d.ts.map +1 -0
- package/dist/schema/types.js +2 -0
- package/dist/schema/types.js.map +1 -0
- package/dist/search.d.ts +215 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +449 -0
- package/dist/search.js.map +1 -0
- package/dist/settings.d.ts +30 -0
- package/dist/settings.d.ts.map +1 -0
- package/dist/settings.js +74 -0
- package/dist/settings.js.map +1 -0
- package/dist/store.d.ts +284 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +660 -0
- package/dist/store.js.map +1 -0
- package/dist/studio-door.d.ts +187 -0
- package/dist/studio-door.d.ts.map +1 -0
- package/dist/studio-door.js +20 -0
- package/dist/studio-door.js.map +1 -0
- package/dist/sync/conflict.d.ts +37 -0
- package/dist/sync/conflict.d.ts.map +1 -0
- package/dist/sync/conflict.js +56 -0
- package/dist/sync/conflict.js.map +1 -0
- package/dist/sync/engine.d.ts +118 -0
- package/dist/sync/engine.d.ts.map +1 -0
- package/dist/sync/engine.js +341 -0
- package/dist/sync/engine.js.map +1 -0
- package/dist/sync/google-calendar.d.ts +54 -0
- package/dist/sync/google-calendar.d.ts.map +1 -0
- package/dist/sync/google-calendar.js +167 -0
- package/dist/sync/google-calendar.js.map +1 -0
- package/dist/sync/types.d.ts +125 -0
- package/dist/sync/types.d.ts.map +1 -0
- package/dist/sync/types.js +6 -0
- package/dist/sync/types.js.map +1 -0
- package/dist/temporal/effectivity.d.ts +75 -0
- package/dist/temporal/effectivity.d.ts.map +1 -0
- package/dist/temporal/effectivity.js +89 -0
- package/dist/temporal/effectivity.js.map +1 -0
- package/dist/testing.d.ts +63 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +194 -0
- package/dist/testing.js.map +1 -0
- package/dist/theme/contrast.d.ts +47 -0
- package/dist/theme/contrast.d.ts.map +1 -0
- package/dist/theme/contrast.js +172 -0
- package/dist/theme/contrast.js.map +1 -0
- package/dist/theme/derive.d.ts +81 -0
- package/dist/theme/derive.d.ts.map +1 -0
- package/dist/theme/derive.js +171 -0
- package/dist/theme/derive.js.map +1 -0
- package/dist/theme/kit.d.ts +106 -0
- package/dist/theme/kit.d.ts.map +1 -0
- package/dist/theme/kit.js +84 -0
- package/dist/theme/kit.js.map +1 -0
- package/dist/theme/palettes.d.ts +32 -0
- package/dist/theme/palettes.d.ts.map +1 -0
- package/dist/theme/palettes.js +96 -0
- package/dist/theme/palettes.js.map +1 -0
- package/dist/theme/types.d.ts +131 -0
- package/dist/theme/types.d.ts.map +1 -0
- package/dist/theme/types.js +23 -0
- package/dist/theme/types.js.map +1 -0
- package/dist/views/types.d.ts +89 -0
- package/dist/views/types.d.ts.map +1 -0
- package/dist/views/types.js +88 -0
- package/dist/views/types.js.map +1 -0
- package/dist/watched.d.ts +33 -0
- package/dist/watched.d.ts.map +1 -0
- package/dist/watched.js +50 -0
- package/dist/watched.js.map +1 -0
- package/dist/who.d.ts +26 -0
- package/dist/who.d.ts.map +1 -0
- package/dist/who.js +20 -0
- package/dist/who.js.map +1 -0
- package/package.json +77 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { deriveEditMutations } from "./mutations/derive-edits.js";
|
|
2
|
+
import { nodeRefArgs } from "./mutations/node-ref.js";
|
|
3
|
+
/** Every act the app has, declared and derived alike. */
|
|
4
|
+
function actsOf(app) {
|
|
5
|
+
return [...(app.mutations ?? []), ...deriveEditMutations(app.schema, app.mutations ?? [])];
|
|
6
|
+
}
|
|
7
|
+
export function beginning(app) {
|
|
8
|
+
const kinds = [...app.schema.kinds];
|
|
9
|
+
const acts = actsOf(app);
|
|
10
|
+
/** What each act must be handed, as kinds, ignoring optional arguments. */
|
|
11
|
+
const requires = new Map();
|
|
12
|
+
/** What each act makes. */
|
|
13
|
+
const makes = new Map();
|
|
14
|
+
for (const act of acts) {
|
|
15
|
+
makes.set(act.name, (act.creates ?? []));
|
|
16
|
+
const wanted = nodeRefArgs(act.input)
|
|
17
|
+
.filter((arg) => !arg.optional && !arg.kinds.includes("*"))
|
|
18
|
+
.flatMap((arg) => arg.kinds);
|
|
19
|
+
requires.set(act.name, [...new Set(wanted)]);
|
|
20
|
+
}
|
|
21
|
+
const madeBy = new Map();
|
|
22
|
+
for (const kind of kinds)
|
|
23
|
+
madeBy.set(kind, []);
|
|
24
|
+
for (const act of acts) {
|
|
25
|
+
for (const kind of makes.get(act.name) ?? [])
|
|
26
|
+
madeBy.get(kind)?.push(act.name);
|
|
27
|
+
}
|
|
28
|
+
/*
|
|
29
|
+
* THE SHORTEST CHAIN TO EACH KIND, by widening the set of what exists.
|
|
30
|
+
*
|
|
31
|
+
* Start with nothing; take every act whose required kinds are all present;
|
|
32
|
+
* whatever they make now exists, at this depth. Repeat until a pass adds
|
|
33
|
+
* nothing. Kinds left over are unreachable — which includes an act whose
|
|
34
|
+
* only door needs a kind only IT can make, a cycle nobody can enter.
|
|
35
|
+
*/
|
|
36
|
+
const depth = new Map();
|
|
37
|
+
const present = new Set();
|
|
38
|
+
for (let round = 0;; round += 1) {
|
|
39
|
+
const arrived = [];
|
|
40
|
+
for (const act of acts) {
|
|
41
|
+
const wants = requires.get(act.name) ?? [];
|
|
42
|
+
if (!wants.every((kind) => present.has(kind)))
|
|
43
|
+
continue;
|
|
44
|
+
for (const kind of makes.get(act.name) ?? []) {
|
|
45
|
+
if (!present.has(kind))
|
|
46
|
+
arrived.push(kind);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (arrived.length === 0)
|
|
50
|
+
break;
|
|
51
|
+
for (const kind of arrived) {
|
|
52
|
+
present.add(kind);
|
|
53
|
+
depth.set(kind, round);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
const needsOf = (kind) => {
|
|
57
|
+
const doors = madeBy.get(kind) ?? [];
|
|
58
|
+
if (doors.length === 0)
|
|
59
|
+
return [];
|
|
60
|
+
/* The cheapest door decides, because one open door is enough. */
|
|
61
|
+
const cheapest = doors
|
|
62
|
+
.map((name) => requires.get(name) ?? [])
|
|
63
|
+
.sort((a, b) => a.length - b.length)[0];
|
|
64
|
+
return [...new Set(cheapest)].filter((wanted) => wanted !== kind);
|
|
65
|
+
};
|
|
66
|
+
const order = kinds
|
|
67
|
+
.map((kind) => ({
|
|
68
|
+
kind,
|
|
69
|
+
madeBy: [...(madeBy.get(kind) ?? [])].sort(),
|
|
70
|
+
needs: [...needsOf(kind)].sort(),
|
|
71
|
+
depth: depth.get(kind) ?? null,
|
|
72
|
+
}))
|
|
73
|
+
.sort((a, b) => (a.depth ?? Number.MAX_SAFE_INTEGER) - (b.depth ?? Number.MAX_SAFE_INTEGER) ||
|
|
74
|
+
a.kind.localeCompare(b.kind));
|
|
75
|
+
const roots = order.filter((entry) => entry.depth === 0).map((entry) => entry.kind);
|
|
76
|
+
const doors = [
|
|
77
|
+
...new Set(acts
|
|
78
|
+
.filter((act) => (requires.get(act.name) ?? []).length === 0)
|
|
79
|
+
.filter((act) => (makes.get(act.name) ?? []).length > 0)
|
|
80
|
+
.map((act) => act.name)),
|
|
81
|
+
].sort();
|
|
82
|
+
const unreachable = order
|
|
83
|
+
.filter((entry) => entry.depth === null)
|
|
84
|
+
.map((entry) => ({
|
|
85
|
+
kind: entry.kind,
|
|
86
|
+
why: entry.madeBy.length === 0
|
|
87
|
+
? "no act declares that it creates this kind"
|
|
88
|
+
: `every act that makes it needs ${entry.needs
|
|
89
|
+
.map((kind) => `"${kind}"`)
|
|
90
|
+
.join(", ")}, which nothing can make first`,
|
|
91
|
+
}));
|
|
92
|
+
return { order, roots, doors, unreachable };
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=beginning.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"beginning.js","sourceRoot":"","sources":["../src/beginning.ts"],"names":[],"mappings":"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"}
|
package/dist/bind.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { z } from "zod";
|
|
2
|
+
import type { InvariantDefinition, InvariantEvalArgs, Violation } from "./invariants/types.js";
|
|
3
|
+
import type { MutationDefinition, MutationDefinitionSpec } from "./mutations/types.js";
|
|
4
|
+
import type { AnySchema, KindOfSchema, NodeOfKind } from "./schema/schema.js";
|
|
5
|
+
import { type ViewRegistry } from "./views/types.js";
|
|
6
|
+
export interface SchemaBinding<S extends AnySchema> {
|
|
7
|
+
readonly schema: S;
|
|
8
|
+
/**
|
|
9
|
+
* Declares a mutation against this schema. Binding the schema up front is
|
|
10
|
+
* what lets TypeScript infer the argument type from `input` — so a
|
|
11
|
+
* mutation body sees real field types, and a renamed field breaks the
|
|
12
|
+
* build rather than the app.
|
|
13
|
+
*/
|
|
14
|
+
defineMutation<const Name extends string, I extends z.ZodType>(name: Name, spec: MutationDefinitionSpec<S, I>): MutationDefinition<S, Name, I>;
|
|
15
|
+
defineInvariant<const K extends KindOfSchema<S>>(name: string, spec: {
|
|
16
|
+
readonly scope: {
|
|
17
|
+
readonly kind: K;
|
|
18
|
+
readonly match?: (node: NodeOfKind<S, K>) => boolean;
|
|
19
|
+
};
|
|
20
|
+
readonly label?: string;
|
|
21
|
+
readonly description?: string;
|
|
22
|
+
readonly repairs?: readonly string[];
|
|
23
|
+
/** Judge retired subjects too — see `InvariantDefinition.judgesPast`. */
|
|
24
|
+
readonly judgesPast?: boolean;
|
|
25
|
+
readonly evaluate: (args: InvariantEvalArgs<S, NodeOfKind<S, K>>) => Violation[];
|
|
26
|
+
}): InvariantDefinition<S>;
|
|
27
|
+
defineGraphInvariant(name: string, spec: {
|
|
28
|
+
readonly label?: string;
|
|
29
|
+
readonly description?: string;
|
|
30
|
+
readonly repairs?: readonly string[];
|
|
31
|
+
readonly evaluate: (args: InvariantEvalArgs<S, undefined>) => Violation[];
|
|
32
|
+
}): InvariantDefinition<S>;
|
|
33
|
+
createViews<V = unknown>(): ViewRegistry<S, V>;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Binds a schema so everything declared against it infers from it. Without
|
|
37
|
+
* this, TypeScript cannot infer a mutation's argument type and the schema
|
|
38
|
+
* type at once — and an argument typed `unknown` defeats the whole point of
|
|
39
|
+
* declaring the schema.
|
|
40
|
+
*/
|
|
41
|
+
export declare function bindSchema<S extends AnySchema>(schema: S): SchemaBinding<S>;
|
|
42
|
+
//# sourceMappingURL=bind.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bind.d.ts","sourceRoot":"","sources":["../src/bind.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAE7B,OAAO,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAC/F,OAAO,KAAK,EACV,kBAAkB,EAClB,sBAAsB,EACvB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEzE,MAAM,WAAW,aAAa,CAAC,CAAC,SAAS,SAAS;IAChD,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IACnB;;;;;OAKG;IACH,cAAc,CAAC,KAAK,CAAC,IAAI,SAAS,MAAM,EAAE,CAAC,SAAS,CAAC,CAAC,OAAO,EAC3D,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,sBAAsB,CAAC,CAAC,EAAE,CAAC,CAAC,GACjC,kBAAkB,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAClC,eAAe,CAAC,KAAK,CAAC,CAAC,SAAS,YAAY,CAAC,CAAC,CAAC,EAC7C,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE;QACJ,QAAQ,CAAC,KAAK,EAAE;YAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;YAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,OAAO,CAAA;SAAE,CAAC;QAC3F,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAC9B,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;QACrC,yEAAyE;QACzE,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;QAC9B,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;KAClF,GACA,mBAAmB,CAAC,CAAC,CAAC,CAAC;IAC1B,oBAAoB,CAClB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE;QACJ,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAC9B,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;QACrC,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC,EAAE,SAAS,CAAC,KAAK,SAAS,EAAE,CAAC;KAC3E,GACA,mBAAmB,CAAC,CAAC,CAAC,CAAC;IAC1B,WAAW,CAAC,CAAC,GAAG,OAAO,KAAK,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CAChD;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,SAAS,EAAE,MAAM,EAAE,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAgB3E"}
|
package/dist/bind.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { defineInvariant } from "./invariants/engine.js";
|
|
2
|
+
import { createViewRegistry } from "./views/types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Binds a schema so everything declared against it infers from it. Without
|
|
5
|
+
* this, TypeScript cannot infer a mutation's argument type and the schema
|
|
6
|
+
* type at once — and an argument typed `unknown` defeats the whole point of
|
|
7
|
+
* declaring the schema.
|
|
8
|
+
*/
|
|
9
|
+
export function bindSchema(schema) {
|
|
10
|
+
return {
|
|
11
|
+
schema,
|
|
12
|
+
defineMutation(name, spec) {
|
|
13
|
+
return { ...spec, name };
|
|
14
|
+
},
|
|
15
|
+
defineInvariant(name, spec) {
|
|
16
|
+
return defineInvariant(name, spec);
|
|
17
|
+
},
|
|
18
|
+
defineGraphInvariant(name, spec) {
|
|
19
|
+
return defineInvariant(name, { ...spec, scope: "graph" });
|
|
20
|
+
},
|
|
21
|
+
createViews() {
|
|
22
|
+
return createViewRegistry(schema);
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=bind.js.map
|
package/dist/bind.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bind.js","sourceRoot":"","sources":["../src/bind.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAOzD,OAAO,EAAE,kBAAkB,EAAqB,MAAM,kBAAkB,CAAC;AAsCzE;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAsB,MAAS;IACvD,OAAO;QACL,MAAM;QACN,cAAc,CAAC,IAAI,EAAE,IAAI;YACvB,OAAO,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,CAAC;QAC3B,CAAC;QACD,eAAe,CAAC,IAAI,EAAE,IAAI;YACxB,OAAO,eAAe,CAAqB,IAAI,EAAE,IAAa,CAAC,CAAC;QAClE,CAAC;QACD,oBAAoB,CAAC,IAAI,EAAE,IAAI;YAC7B,OAAO,eAAe,CAAI,IAAI,EAAE,EAAE,GAAG,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;QAC/D,CAAC;QACD,WAAW;YACT,OAAO,kBAAkB,CAAO,MAAM,CAAC,CAAC;QAC1C,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/dist/city.d.ts
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import type { AnySchema } from "./schema/schema.js";
|
|
2
|
+
/**
|
|
3
|
+
* THE CITY IS A MAP DRAWN FROM THE DECLARATION.
|
|
4
|
+
*
|
|
5
|
+
* A kind is a neighbourhood, and where it stands is decided by the
|
|
6
|
+
* declaration alone — never by today's data, never by what looks nice.
|
|
7
|
+
* Same declaration, same map; add a kind and every existing plot stays
|
|
8
|
+
* where it was; a kind that grows takes a bigger block on the same corner.
|
|
9
|
+
* That is what makes an address an address: the place a person remembers
|
|
10
|
+
* is the place they get.
|
|
11
|
+
*
|
|
12
|
+
* Units are LATTICE CELLS on the isometric ground, not pixels. `col` runs
|
|
13
|
+
* down-right along one diagonal, `row` down-left along the other; a plot
|
|
14
|
+
* occupies `side × side` cells from its corner. Plots sit on a block grid
|
|
15
|
+
* one `BLOCK` apart, so a plot growing to its largest side never reaches
|
|
16
|
+
* its neighbour: the street between is the cell left over.
|
|
17
|
+
*
|
|
18
|
+
* Placement walks the kinds in the order the declaration says a blank
|
|
19
|
+
* installation fills them (`beginning(app).order`, or sorted ids when
|
|
20
|
+
* nobody said), puts the first at the origin, and puts each next kind in
|
|
21
|
+
* the free block adjacent to the placed kind it shares the most declared
|
|
22
|
+
* edges with — ties by id — spiralling outward when the near blocks are
|
|
23
|
+
* taken. A kind declaring `plot` is put exactly there.
|
|
24
|
+
*/
|
|
25
|
+
export interface Plot {
|
|
26
|
+
/** Corner cell, in lattice units. Multiples of BLOCK unless declared. */
|
|
27
|
+
readonly col: number;
|
|
28
|
+
readonly row: number;
|
|
29
|
+
/** Cells on a side: ceil(sqrt(count)), at least 1, at most MAX_SIDE. */
|
|
30
|
+
readonly side: number;
|
|
31
|
+
}
|
|
32
|
+
/** The most cells a plot takes on a side. */
|
|
33
|
+
export declare const MAX_SIDE = 4;
|
|
34
|
+
/** Block pitch: the largest side plus one cell of street. */
|
|
35
|
+
export declare const BLOCK: number;
|
|
36
|
+
export interface CityHints {
|
|
37
|
+
/** The kind chain a blank installation fills, first to last. */
|
|
38
|
+
readonly order?: readonly string[];
|
|
39
|
+
/** How many of each kind stand today. Changes side, never col or row. */
|
|
40
|
+
readonly counts?: Readonly<Record<string, number>>;
|
|
41
|
+
/** Hand-laid plots, by kind. Used verbatim; a declared `plot` on the kind wins first. */
|
|
42
|
+
readonly plots?: Readonly<Record<string, {
|
|
43
|
+
readonly col: number;
|
|
44
|
+
readonly row: number;
|
|
45
|
+
}>>;
|
|
46
|
+
}
|
|
47
|
+
export type CityMap = ReadonlyMap<string, Plot>;
|
|
48
|
+
/** A road: two kinds joined by declared edges, and which edges. */
|
|
49
|
+
export interface Road {
|
|
50
|
+
readonly from: string;
|
|
51
|
+
readonly to: string;
|
|
52
|
+
readonly edges: readonly string[];
|
|
53
|
+
}
|
|
54
|
+
/** Cells on a side for a population. */
|
|
55
|
+
export declare function sideFor(count: number | undefined): number;
|
|
56
|
+
/**
|
|
57
|
+
* How many declared edges join two kinds, either direction. A wildcard
|
|
58
|
+
* edge touches every kind and counts once toward each.
|
|
59
|
+
*/
|
|
60
|
+
export declare function sharedEdges(schema: AnySchema, a: string, b: string): number;
|
|
61
|
+
export declare function cityMap(schema: AnySchema, hints?: CityHints): CityMap;
|
|
62
|
+
/** The roads between placed kinds: one per pair joined by any declared edge. */
|
|
63
|
+
export declare function roadsOf(schema: AnySchema, map: CityMap): readonly Road[];
|
|
64
|
+
/**
|
|
65
|
+
* Two plots overlap when their blocks do — the checker's question about
|
|
66
|
+
* hand-laid plots, asked at the block size so a plot growing to its
|
|
67
|
+
* largest side can never reach a neighbour.
|
|
68
|
+
*/
|
|
69
|
+
export declare function plotsOverlap(a: {
|
|
70
|
+
readonly col: number;
|
|
71
|
+
readonly row: number;
|
|
72
|
+
}, b: {
|
|
73
|
+
readonly col: number;
|
|
74
|
+
readonly row: number;
|
|
75
|
+
}): boolean;
|
|
76
|
+
/** The map's extent in lattice cells: the smallest box holding every plot at its side. */
|
|
77
|
+
export declare function cityExtent(map: CityMap): {
|
|
78
|
+
readonly minCol: number;
|
|
79
|
+
readonly minRow: number;
|
|
80
|
+
readonly maxCol: number;
|
|
81
|
+
readonly maxRow: number;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* THE 2:1 LATTICE, as a projection. A cell (col,row) meets the screen at
|
|
85
|
+
* x = (col − row) · w/2, y = (col + row) · h/2 with h = w/2 — the same
|
|
86
|
+
* pitch the ground's CSS draws (lines at ±atan 2), so a plot placed here
|
|
87
|
+
* sits on the grid a person can see.
|
|
88
|
+
*/
|
|
89
|
+
export declare function toIso(col: number, row: number, cell: number): {
|
|
90
|
+
readonly x: number;
|
|
91
|
+
readonly y: number;
|
|
92
|
+
};
|
|
93
|
+
//# sourceMappingURL=city.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"city.d.ts","sourceRoot":"","sources":["../src/city.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEpD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,MAAM,WAAW,IAAI;IACnB,yEAAyE;IACzE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,wEAAwE;IACxE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,6CAA6C;AAC7C,eAAO,MAAM,QAAQ,IAAI,CAAC;AAC1B,6DAA6D;AAC7D,eAAO,MAAM,KAAK,QAAe,CAAC;AAElC,MAAM,WAAW,SAAS;IACxB,gEAAgE;IAChE,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,yEAAyE;IACzE,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACnD,yFAAyF;IACzF,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;CAC3F;AAED,MAAM,MAAM,OAAO,GAAG,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAEhD,mEAAmE;AACnE,MAAM,WAAW,IAAI;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC;AAID,wCAAwC;AACxC,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAGzD;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAe3E;AAsBD,wBAAgB,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,GAAE,SAAc,GAAG,OAAO,CAgDzE;AAED,gFAAgF;AAChF,wBAAgB,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,OAAO,GAAG,SAAS,IAAI,EAAE,CAsBxE;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EAAE,CAAC,EAAE;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAE1I;AAED,0FAA0F;AAC1F,wBAAgB,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAa/I;AAED;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG;IAAE,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAExG"}
|
package/dist/city.js
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/** The most cells a plot takes on a side. */
|
|
2
|
+
export const MAX_SIDE = 4;
|
|
3
|
+
/** Block pitch: the largest side plus one cell of street. */
|
|
4
|
+
export const BLOCK = MAX_SIDE + 1;
|
|
5
|
+
const byId = (a, b) => (a < b ? -1 : a > b ? 1 : 0);
|
|
6
|
+
/** Cells on a side for a population. */
|
|
7
|
+
export function sideFor(count) {
|
|
8
|
+
if (!count || count <= 1)
|
|
9
|
+
return 1;
|
|
10
|
+
return Math.min(MAX_SIDE, Math.ceil(Math.sqrt(count)));
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* How many declared edges join two kinds, either direction. A wildcard
|
|
14
|
+
* edge touches every kind and counts once toward each.
|
|
15
|
+
*/
|
|
16
|
+
export function sharedEdges(schema, a, b) {
|
|
17
|
+
if (a === b)
|
|
18
|
+
return 0;
|
|
19
|
+
const kinds = schema.kinds;
|
|
20
|
+
let shared = 0;
|
|
21
|
+
for (const [from, to] of [
|
|
22
|
+
[a, b],
|
|
23
|
+
[b, a],
|
|
24
|
+
]) {
|
|
25
|
+
const definition = schema.tryDefinition(from);
|
|
26
|
+
for (const declaration of Object.values(definition?.edges ?? {})) {
|
|
27
|
+
const targets = declaration.to === "*" ? kinds : declaration.to;
|
|
28
|
+
if (targets.includes(to))
|
|
29
|
+
shared += 1;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return shared;
|
|
33
|
+
}
|
|
34
|
+
/** The block cells a plot at (col,row) reserves: every cell of the block. */
|
|
35
|
+
const blockKey = (col, row) => `${Math.floor(col / BLOCK)},${Math.floor(row / BLOCK)}`;
|
|
36
|
+
/**
|
|
37
|
+
* Blocks around `(col,row)` at Manhattan distance `d`, in a stable order:
|
|
38
|
+
* the four cardinal neighbours first (down-right, down-left, up-left,
|
|
39
|
+
* up-right), then the rest clockwise. Deterministic, so the walk is.
|
|
40
|
+
*/
|
|
41
|
+
function ringAround(col, row, d) {
|
|
42
|
+
if (d === 0)
|
|
43
|
+
return [{ col, row }];
|
|
44
|
+
const out = [];
|
|
45
|
+
for (let i = 0; i < d; i++) {
|
|
46
|
+
out.push({ col: col + (d - i) * BLOCK, row: row + i * BLOCK });
|
|
47
|
+
out.push({ col: col - i * BLOCK, row: row + (d - i) * BLOCK });
|
|
48
|
+
out.push({ col: col - (d - i) * BLOCK, row: row - i * BLOCK });
|
|
49
|
+
out.push({ col: col + i * BLOCK, row: row - (d - i) * BLOCK });
|
|
50
|
+
}
|
|
51
|
+
return out;
|
|
52
|
+
}
|
|
53
|
+
export function cityMap(schema, hints = {}) {
|
|
54
|
+
const kinds = [...schema.kinds];
|
|
55
|
+
const order = [
|
|
56
|
+
...(hints.order ?? []).filter((kind) => kinds.includes(kind)),
|
|
57
|
+
...kinds.filter((kind) => !(hints.order ?? []).includes(kind)).sort(byId),
|
|
58
|
+
].filter((kind, index, all) => all.indexOf(kind) === index);
|
|
59
|
+
const plots = new Map();
|
|
60
|
+
const taken = new Set();
|
|
61
|
+
const put = (kind, col, row) => {
|
|
62
|
+
plots.set(kind, { col, row, side: sideFor(hints.counts?.[kind]) });
|
|
63
|
+
taken.add(blockKey(col, row));
|
|
64
|
+
};
|
|
65
|
+
/* HAND-LAID FIRST, verbatim: a declared address is an address. */
|
|
66
|
+
for (const kind of order) {
|
|
67
|
+
const declared = schema.tryDefinition(kind)?.plot ?? hints.plots?.[kind];
|
|
68
|
+
if (declared)
|
|
69
|
+
put(kind, declared.col, declared.row);
|
|
70
|
+
}
|
|
71
|
+
for (const kind of order) {
|
|
72
|
+
if (plots.has(kind))
|
|
73
|
+
continue;
|
|
74
|
+
if (plots.size === 0) {
|
|
75
|
+
put(kind, 0, 0);
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
/*
|
|
79
|
+
* THE PLACED KIND IT SHARES THE MOST EDGES WITH. None shared means
|
|
80
|
+
* nothing to be near, and the city's first block is the anchor — so an
|
|
81
|
+
* unrelated kind still lands near the middle rather than off on its own.
|
|
82
|
+
*/
|
|
83
|
+
let anchor;
|
|
84
|
+
let most = 0;
|
|
85
|
+
for (const placed of [...plots.keys()].sort(byId)) {
|
|
86
|
+
const shared = sharedEdges(schema, kind, placed);
|
|
87
|
+
if (shared > most || (shared === most && shared > 0 && anchor !== undefined && byId(placed, anchor) < 0)) {
|
|
88
|
+
most = shared;
|
|
89
|
+
anchor = placed;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
const from = anchor ? plots.get(anchor) : plots.get(order.find((k) => plots.has(k)));
|
|
93
|
+
let found;
|
|
94
|
+
for (let d = 1; !found && d < 64; d++) {
|
|
95
|
+
found = ringAround(from.col, from.row, d).find((cell) => !taken.has(blockKey(cell.col, cell.row)));
|
|
96
|
+
}
|
|
97
|
+
put(kind, found?.col ?? from.col + BLOCK * plots.size, found?.row ?? from.row);
|
|
98
|
+
}
|
|
99
|
+
return plots;
|
|
100
|
+
}
|
|
101
|
+
/** The roads between placed kinds: one per pair joined by any declared edge. */
|
|
102
|
+
export function roadsOf(schema, map) {
|
|
103
|
+
const kinds = [...map.keys()].sort(byId);
|
|
104
|
+
const roads = [];
|
|
105
|
+
for (let i = 0; i < kinds.length; i++) {
|
|
106
|
+
for (let j = i + 1; j < kinds.length; j++) {
|
|
107
|
+
const a = kinds[i];
|
|
108
|
+
const b = kinds[j];
|
|
109
|
+
const edges = [];
|
|
110
|
+
for (const [from, to] of [
|
|
111
|
+
[a, b],
|
|
112
|
+
[b, a],
|
|
113
|
+
]) {
|
|
114
|
+
const definition = schema.tryDefinition(from);
|
|
115
|
+
for (const [name, declaration] of Object.entries(definition?.edges ?? {})) {
|
|
116
|
+
const targets = declaration.to === "*" ? schema.kinds : declaration.to;
|
|
117
|
+
if (targets.includes(to))
|
|
118
|
+
edges.push(name);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
if (edges.length > 0)
|
|
122
|
+
roads.push({ from: a, to: b, edges });
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return roads;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Two plots overlap when their blocks do — the checker's question about
|
|
129
|
+
* hand-laid plots, asked at the block size so a plot growing to its
|
|
130
|
+
* largest side can never reach a neighbour.
|
|
131
|
+
*/
|
|
132
|
+
export function plotsOverlap(a, b) {
|
|
133
|
+
return Math.abs(a.col - b.col) < BLOCK && Math.abs(a.row - b.row) < BLOCK;
|
|
134
|
+
}
|
|
135
|
+
/** The map's extent in lattice cells: the smallest box holding every plot at its side. */
|
|
136
|
+
export function cityExtent(map) {
|
|
137
|
+
let minCol = Infinity;
|
|
138
|
+
let minRow = Infinity;
|
|
139
|
+
let maxCol = -Infinity;
|
|
140
|
+
let maxRow = -Infinity;
|
|
141
|
+
for (const plot of map.values()) {
|
|
142
|
+
minCol = Math.min(minCol, plot.col);
|
|
143
|
+
minRow = Math.min(minRow, plot.row);
|
|
144
|
+
maxCol = Math.max(maxCol, plot.col + plot.side);
|
|
145
|
+
maxRow = Math.max(maxRow, plot.row + plot.side);
|
|
146
|
+
}
|
|
147
|
+
if (map.size === 0)
|
|
148
|
+
return { minCol: 0, minRow: 0, maxCol: 1, maxRow: 1 };
|
|
149
|
+
return { minCol, minRow, maxCol, maxRow };
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* THE 2:1 LATTICE, as a projection. A cell (col,row) meets the screen at
|
|
153
|
+
* x = (col − row) · w/2, y = (col + row) · h/2 with h = w/2 — the same
|
|
154
|
+
* pitch the ground's CSS draws (lines at ±atan 2), so a plot placed here
|
|
155
|
+
* sits on the grid a person can see.
|
|
156
|
+
*/
|
|
157
|
+
export function toIso(col, row, cell) {
|
|
158
|
+
return { x: ((col - row) * cell) / 2, y: ((col + row) * cell) / 4 };
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=city.js.map
|
package/dist/city.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"city.js","sourceRoot":"","sources":["../src/city.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { AnySchema } from "../../schema/schema.js";
|
|
2
|
+
import type { CheckContext } from "./context.js";
|
|
3
|
+
/**
|
|
4
|
+
* WHAT A KIND SAYS IT IS ARRANGED BY has to be something it has.
|
|
5
|
+
*
|
|
6
|
+
* `fieldRoles.order` names the field a kind sorts by when nothing is asked;
|
|
7
|
+
* a lens's `arrangedBy` names how its picture opens. Both are strings in a
|
|
8
|
+
* declaration that nothing else reads until a person is looking, so a
|
|
9
|
+
* renamed field would leave a picture quietly opening unsorted. The
|
|
10
|
+
* arrangement module already knows what each kind offers; this asks it.
|
|
11
|
+
*/
|
|
12
|
+
export declare function checkArrangement<S extends AnySchema>(ctx: CheckContext<S>): void;
|
|
13
|
+
//# sourceMappingURL=arrangement.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arrangement.d.ts","sourceRoot":"","sources":["../../../src/cli/check/arrangement.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,SAAS,EAAE,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,IAAI,CA6ChF"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { admitArrangement, arrangeable, parseArrangement } from "../../arrange.js";
|
|
2
|
+
/**
|
|
3
|
+
* WHAT A KIND SAYS IT IS ARRANGED BY has to be something it has.
|
|
4
|
+
*
|
|
5
|
+
* `fieldRoles.order` names the field a kind sorts by when nothing is asked;
|
|
6
|
+
* a lens's `arrangedBy` names how its picture opens. Both are strings in a
|
|
7
|
+
* declaration that nothing else reads until a person is looking, so a
|
|
8
|
+
* renamed field would leave a picture quietly opening unsorted. The
|
|
9
|
+
* arrangement module already knows what each kind offers; this asks it.
|
|
10
|
+
*/
|
|
11
|
+
export function checkArrangement(ctx) {
|
|
12
|
+
const { app, add } = ctx;
|
|
13
|
+
for (const definition of app.schema.definitions) {
|
|
14
|
+
const order = definition.fieldRoles?.["order"];
|
|
15
|
+
if (order === undefined)
|
|
16
|
+
continue;
|
|
17
|
+
const shape = (definition.fields.shape ?? {});
|
|
18
|
+
if (order === "label" || order in shape)
|
|
19
|
+
continue;
|
|
20
|
+
add({
|
|
21
|
+
severity: "warning",
|
|
22
|
+
code: "order-role-unknown",
|
|
23
|
+
where: `defineNode("${definition.kind}").fieldRoles.order`,
|
|
24
|
+
message: `"${definition.kind}" says it sorts by "${order}", and has no such field — so nothing sorts it.`,
|
|
25
|
+
fix: `Point order at one of ${Object.keys(shape).join(", ") || "its fields"}, or drop it.`,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
for (const lens of app.lenses ?? []) {
|
|
29
|
+
if (!lens.arrangedBy)
|
|
30
|
+
continue;
|
|
31
|
+
/*
|
|
32
|
+
* The kinds a lens is bound over: the keys of a fields binding, or the
|
|
33
|
+
* kinds an entities binding names. An arrangement is admitted against
|
|
34
|
+
* each; what none of them offers is noted.
|
|
35
|
+
*/
|
|
36
|
+
const bound = new Set();
|
|
37
|
+
for (const [key, binding] of Object.entries(lens.bindings ?? {})) {
|
|
38
|
+
if (lens.binds === "entities") {
|
|
39
|
+
const kind = binding.kind;
|
|
40
|
+
if (typeof kind === "string")
|
|
41
|
+
bound.add(kind);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
bound.add(key);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (bound.size === 0)
|
|
48
|
+
continue;
|
|
49
|
+
const asked = parseArrangement(lens.arrangedBy);
|
|
50
|
+
const dropped = [...bound].map((kind) => admitArrangement(asked, arrangeable(app.schema, kind)).dropped);
|
|
51
|
+
const byEvery = dropped.length > 0 ? dropped.reduce((common, these) => common.filter((part) => these.includes(part))) : [];
|
|
52
|
+
for (const part of byEvery) {
|
|
53
|
+
add({
|
|
54
|
+
severity: "note",
|
|
55
|
+
code: "lens-arrangement-unknown",
|
|
56
|
+
where: `lens "${lens.name}" arrangedBy`,
|
|
57
|
+
message: `The lens opens arranged by "${part}", and none of ${[...bound].join(", ")} can be arranged that way — the picture will open unarranged there.`,
|
|
58
|
+
fix: `Name a field, an edge or \`is\` the bound kind has; \`graview describe\` lists what each kind can be arranged by.`,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=arrangement.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arrangement.js","sourceRoot":"","sources":["../../../src/cli/check/arrangement.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { AnySchema } from "../../schema/schema.js";
|
|
2
|
+
/**
|
|
3
|
+
* `note` is a QUESTION ASKED OUT LOUD, not a problem.
|
|
4
|
+
*
|
|
5
|
+
* Some things a checker can see are legitimate designs that the author
|
|
6
|
+
* should nonetheless have looked at once: a lens written for this app and
|
|
7
|
+
* never proved against another domain, a role name two vocabularies both
|
|
8
|
+
* use, a kind unreachable on an empty graph. Filed as warnings they would
|
|
9
|
+
* be warnings that can only ever be acknowledged, and those are the ones
|
|
10
|
+
* people learn to scroll past — which costs the checker its authority on
|
|
11
|
+
* the warnings that matter. So they have their own voice: counted, printed,
|
|
12
|
+
* and never a failure.
|
|
13
|
+
*/
|
|
14
|
+
import type { CheckContext } from "./context.js";
|
|
15
|
+
export declare function checkBlankInstallation<S extends AnySchema>(ctx: CheckContext<S>): void;
|
|
16
|
+
//# sourceMappingURL=beginnings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"beginnings.d.ts","sourceRoot":"","sources":["../../../src/cli/check/beginnings.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAExD;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,SAAS,EAAE,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,IAAI,CAgDtF"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { beginning } from "../../beginning.js";
|
|
2
|
+
export function checkBlankInstallation(ctx) {
|
|
3
|
+
const { app, kinds, add } = ctx;
|
|
4
|
+
/*
|
|
5
|
+
* WHAT A BLANK INSTALLATION CAN ACTUALLY DO.
|
|
6
|
+
*
|
|
7
|
+
* `creates` and a nodeRef argument are together a chain — a feature cannot
|
|
8
|
+
* be made until a zone exists — and it is invisible at build time: the
|
|
9
|
+
* declaration is well-formed, every act is correct, and the gap only
|
|
10
|
+
* appears at runtime on the one graph nobody tests against. A ten-kind app
|
|
11
|
+
* can ship with one door and seven silent districts, and the first person
|
|
12
|
+
* to open it is the first to find out.
|
|
13
|
+
*
|
|
14
|
+
* Notes rather than warnings, because every answer here is a legitimate
|
|
15
|
+
* design: a kind a migration seeds, a catalogue that arrives whole, a
|
|
16
|
+
* product whose data comes from a sync. The author should have to look at
|
|
17
|
+
* it once, not argue with it forever.
|
|
18
|
+
*/
|
|
19
|
+
const chain = beginning(app);
|
|
20
|
+
/*
|
|
21
|
+
* Only an app that says it MAKES things is asked how. An app whose every
|
|
22
|
+
* act edits what is already there — a catalogue, a graph that arrives by
|
|
23
|
+
* seed or sync — never claimed a way in, and telling it there is none is
|
|
24
|
+
* a note with no question in it.
|
|
25
|
+
*/
|
|
26
|
+
const claimsToMake = (app.mutations ?? []).some((mutation) => (mutation.creates ?? []).length > 0);
|
|
27
|
+
if (!claimsToMake) {
|
|
28
|
+
// Nothing to say: creation is not this app's business.
|
|
29
|
+
}
|
|
30
|
+
else if (chain.doors.length === 0 && kinds.size > 0) {
|
|
31
|
+
add({
|
|
32
|
+
severity: "note",
|
|
33
|
+
code: "blank-graph-has-no-door",
|
|
34
|
+
where: "mutations",
|
|
35
|
+
message: `Nothing can be made in an empty ${app.name}: every act that creates a kind needs a node that does not exist yet.`,
|
|
36
|
+
fix: `If the graph arrives seeded or synced, that is the answer and this is just the note. Otherwise give one act no required nodeRef, so a blank installation has a way in.`,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
else if (chain.unreachable.length > 0) {
|
|
40
|
+
add({
|
|
41
|
+
severity: "note",
|
|
42
|
+
code: "blank-graph-unreachable",
|
|
43
|
+
where: "mutations",
|
|
44
|
+
message: `${chain.unreachable
|
|
45
|
+
.map((entry) => `"${entry.kind}"`)
|
|
46
|
+
.join(", ")} cannot be made from empty — ${chain.unreachable[0].why}. The way in is ${chain.doors
|
|
47
|
+
.map((door) => `"${door}"`)
|
|
48
|
+
.join(", ")}.`,
|
|
49
|
+
fix: `Declare creates: ["<kind>"] on the act that adds one, or accept that these arrive by seed, migration or sync.`,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=beginnings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"beginnings.js","sourceRoot":"","sources":["../../../src/cli/check/beginnings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAiB/C,MAAM,UAAU,sBAAsB,CAAsB,GAAoB;IAC9E,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;IAChC;;;;;;;;;;;;;;OAcG;IACH,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;IAC7B;;;;;OAKG;IACH,MAAM,YAAY,GAAG,CAAC,GAAG,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACnG,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,uDAAuD;IACzD,CAAC;SAAM,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;QACtD,GAAG,CAAC;YACF,QAAQ,EAAE,MAAM;YAChB,IAAI,EAAE,yBAAyB;YAC/B,KAAK,EAAE,WAAW;YAClB,OAAO,EAAE,mCAAmC,GAAG,CAAC,IAAI,uEAAuE;YAC3H,GAAG,EAAE,wKAAwK;SAC9K,CAAC,CAAC;IACL,CAAC;SAAM,IAAI,KAAK,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxC,GAAG,CAAC;YACF,QAAQ,EAAE,MAAM;YAChB,IAAI,EAAE,yBAAyB;YAC/B,KAAK,EAAE,WAAW;YAClB,OAAO,EAAE,GAAG,KAAK,CAAC,WAAW;iBAC1B,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,KAAK,CAAC,IAAI,GAAG,CAAC;iBACjC,IAAI,CAAC,IAAI,CAAC,gCAAgC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAE,CAAC,GAAG,mBAAmB,KAAK,CAAC,KAAK;iBACjG,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,GAAG,CAAC;iBAC1B,IAAI,CAAC,IAAI,CAAC,GAAG;YAChB,GAAG,EAAE,+GAA+G;SACrH,CAAC,CAAC;IACL,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { AnySchema } from "../../schema/schema.js";
|
|
2
|
+
/**
|
|
3
|
+
* `note` is a QUESTION ASKED OUT LOUD, not a problem.
|
|
4
|
+
*
|
|
5
|
+
* Some things a checker can see are legitimate designs that the author
|
|
6
|
+
* should nonetheless have looked at once: a lens written for this app and
|
|
7
|
+
* never proved against another domain, a role name two vocabularies both
|
|
8
|
+
* use, a kind unreachable on an empty graph. Filed as warnings they would
|
|
9
|
+
* be warnings that can only ever be acknowledged, and those are the ones
|
|
10
|
+
* people learn to scroll past — which costs the checker its authority on
|
|
11
|
+
* the warnings that matter. So they have their own voice: counted, printed,
|
|
12
|
+
* and never a failure.
|
|
13
|
+
*/
|
|
14
|
+
import type { CheckContext } from "./context.js";
|
|
15
|
+
export declare function checkAccents<S extends AnySchema>(ctx: CheckContext<S>): void;
|
|
16
|
+
export declare function checkPalette<S extends AnySchema>(ctx: CheckContext<S>): void;
|
|
17
|
+
//# sourceMappingURL=brand.d.ts.map
|