@graview/core 0.1.0 → 0.1.2
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/README.md +7 -0
- package/dist/app.d.ts +17 -0
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js.map +1 -1
- package/dist/arrange.d.ts +3 -2
- package/dist/arrange.d.ts.map +1 -1
- package/dist/arrange.js +19 -2
- package/dist/arrange.js.map +1 -1
- package/dist/beginning.d.ts +5 -2
- package/dist/beginning.d.ts.map +1 -1
- package/dist/beginning.js +28 -0
- package/dist/beginning.js.map +1 -1
- package/dist/capabilities.d.ts +32 -0
- package/dist/capabilities.d.ts.map +1 -0
- package/dist/capabilities.js +31 -0
- package/dist/capabilities.js.map +1 -0
- package/dist/cli/check/index.d.ts +1 -0
- package/dist/cli/check/index.d.ts.map +1 -1
- package/dist/cli/check/index.js +1 -0
- package/dist/cli/check/index.js.map +1 -1
- package/dist/cli/check/lenses.d.ts.map +1 -1
- package/dist/cli/check/lenses.js +25 -0
- package/dist/cli/check/lenses.js.map +1 -1
- package/dist/cli/check/policy.d.ts.map +1 -1
- package/dist/cli/check/policy.js +35 -0
- package/dist/cli/check/policy.js.map +1 -1
- package/dist/cli/check/relations.d.ts.map +1 -1
- package/dist/cli/check/relations.js +31 -0
- package/dist/cli/check/relations.js.map +1 -1
- package/dist/cli/check/views.d.ts +14 -0
- package/dist/cli/check/views.d.ts.map +1 -0
- package/dist/cli/check/views.js +27 -0
- package/dist/cli/check/views.js.map +1 -0
- package/dist/cli/check.d.ts.map +1 -1
- package/dist/cli/check.js +2 -1
- package/dist/cli/check.js.map +1 -1
- package/dist/cli/create.d.ts +1 -1
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +63 -1
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/index.d.ts +18 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +66 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/conformance/fixtures.d.ts +41 -0
- package/dist/conformance/fixtures.d.ts.map +1 -0
- package/dist/conformance/fixtures.js +950 -0
- package/dist/conformance/fixtures.js.map +1 -0
- package/dist/conformance/index.d.ts +54 -0
- package/dist/conformance/index.d.ts.map +1 -0
- package/dist/conformance/index.js +81 -0
- package/dist/conformance/index.js.map +1 -0
- package/dist/document/canonical.d.ts +4 -0
- package/dist/document/canonical.d.ts.map +1 -0
- package/dist/document/canonical.js +29 -0
- package/dist/document/canonical.js.map +1 -0
- package/dist/document/compile.d.ts +43 -0
- package/dist/document/compile.d.ts.map +1 -0
- package/dist/document/compile.js +787 -0
- package/dist/document/compile.js.map +1 -0
- package/dist/document/diff.d.ts +32 -0
- package/dist/document/diff.d.ts.map +1 -0
- package/dist/document/diff.js +143 -0
- package/dist/document/diff.js.map +1 -0
- package/dist/document/edit.d.ts +63 -0
- package/dist/document/edit.d.ts.map +1 -0
- package/dist/document/edit.js +1420 -0
- package/dist/document/edit.js.map +1 -0
- package/dist/document/expr/analyze.d.ts +14 -0
- package/dist/document/expr/analyze.d.ts.map +1 -0
- package/dist/document/expr/analyze.js +52 -0
- package/dist/document/expr/analyze.js.map +1 -0
- package/dist/document/expr/evaluate.d.ts +36 -0
- package/dist/document/expr/evaluate.d.ts.map +1 -0
- package/dist/document/expr/evaluate.js +344 -0
- package/dist/document/expr/evaluate.js.map +1 -0
- package/dist/document/expr/index.d.ts +8 -0
- package/dist/document/expr/index.d.ts.map +1 -0
- package/dist/document/expr/index.js +5 -0
- package/dist/document/expr/index.js.map +1 -0
- package/dist/document/expr/parse.d.ts +50 -0
- package/dist/document/expr/parse.d.ts.map +1 -0
- package/dist/document/expr/parse.js +240 -0
- package/dist/document/expr/parse.js.map +1 -0
- package/dist/document/expr/print.d.ts +4 -0
- package/dist/document/expr/print.d.ts.map +1 -0
- package/dist/document/expr/print.js +81 -0
- package/dist/document/expr/print.js.map +1 -0
- package/dist/document/findings.d.ts +15 -0
- package/dist/document/findings.d.ts.map +1 -0
- package/dist/document/findings.js +30 -0
- package/dist/document/findings.js.map +1 -0
- package/dist/document/graview-template.d.ts +148 -0
- package/dist/document/graview-template.d.ts.map +1 -0
- package/dist/document/graview-template.js +450 -0
- package/dist/document/graview-template.js.map +1 -0
- package/dist/document/index.d.ts +27 -0
- package/dist/document/index.d.ts.map +1 -0
- package/dist/document/index.js +16 -0
- package/dist/document/index.js.map +1 -0
- package/dist/document/migrate.d.ts +41 -0
- package/dist/document/migrate.d.ts.map +1 -0
- package/dist/document/migrate.js +252 -0
- package/dist/document/migrate.js.map +1 -0
- package/dist/document/patch.d.ts +16 -0
- package/dist/document/patch.d.ts.map +1 -0
- package/dist/document/patch.js +79 -0
- package/dist/document/patch.js.map +1 -0
- package/dist/document/rules.d.ts +40 -0
- package/dist/document/rules.d.ts.map +1 -0
- package/dist/document/rules.js +88 -0
- package/dist/document/rules.js.map +1 -0
- package/dist/document/schema.d.ts +459 -0
- package/dist/document/schema.d.ts.map +1 -0
- package/dist/document/schema.js +197 -0
- package/dist/document/schema.js.map +1 -0
- package/dist/document/template.d.ts +28 -0
- package/dist/document/template.d.ts.map +1 -0
- package/dist/document/template.js +117 -0
- package/dist/document/template.js.map +1 -0
- package/dist/document/to-document.d.ts +34 -0
- package/dist/document/to-document.d.ts.map +1 -0
- package/dist/document/to-document.js +182 -0
- package/dist/document/to-document.js.map +1 -0
- package/dist/document/upgrade.d.ts +9 -0
- package/dist/document/upgrade.d.ts.map +1 -0
- package/dist/document/upgrade.js +19 -0
- package/dist/document/upgrade.js.map +1 -0
- package/dist/document/views.d.ts +65 -0
- package/dist/document/views.d.ts.map +1 -0
- package/dist/document/views.js +264 -0
- package/dist/document/views.js.map +1 -0
- package/dist/formats.d.ts +50 -0
- package/dist/formats.d.ts.map +1 -0
- package/dist/formats.js +75 -0
- package/dist/formats.js.map +1 -0
- package/dist/graph/graph.d.ts +52 -3
- package/dist/graph/graph.d.ts.map +1 -1
- package/dist/graph/graph.js +169 -16
- package/dist/graph/graph.js.map +1 -1
- package/dist/index.d.ts +40 -17
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +29 -10
- package/dist/index.js.map +1 -1
- package/dist/integrity.d.ts +46 -0
- package/dist/integrity.d.ts.map +1 -0
- package/dist/integrity.js +179 -0
- package/dist/integrity.js.map +1 -0
- package/dist/invariants/engine.d.ts +8 -0
- package/dist/invariants/engine.d.ts.map +1 -1
- package/dist/invariants/engine.js +40 -2
- package/dist/invariants/engine.js.map +1 -1
- package/dist/invariants/types.d.ts +19 -0
- package/dist/invariants/types.d.ts.map +1 -1
- package/dist/labels.d.ts +65 -0
- package/dist/labels.d.ts.map +1 -0
- package/dist/labels.js +123 -0
- package/dist/labels.js.map +1 -0
- package/dist/mutations/define-mutation.d.ts.map +1 -1
- package/dist/mutations/define-mutation.js +2 -3
- package/dist/mutations/define-mutation.js.map +1 -1
- package/dist/mutations/derive-edits.d.ts.map +1 -1
- package/dist/mutations/derive-edits.js +20 -1
- package/dist/mutations/derive-edits.js.map +1 -1
- package/dist/mutations/form.d.ts +9 -0
- package/dist/mutations/form.d.ts.map +1 -1
- package/dist/mutations/form.js +20 -0
- package/dist/mutations/form.js.map +1 -1
- package/dist/mutations/node-ref.d.ts +6 -0
- package/dist/mutations/node-ref.d.ts.map +1 -1
- package/dist/mutations/node-ref.js +22 -8
- package/dist/mutations/node-ref.js.map +1 -1
- package/dist/mutations/types.d.ts +8 -0
- package/dist/mutations/types.d.ts.map +1 -1
- package/dist/mutations/words.d.ts +49 -0
- package/dist/mutations/words.d.ts.map +1 -0
- package/dist/mutations/words.js +61 -0
- package/dist/mutations/words.js.map +1 -0
- package/dist/ops/log.d.ts +145 -4
- package/dist/ops/log.d.ts.map +1 -1
- package/dist/ops/log.js +220 -51
- package/dist/ops/log.js.map +1 -1
- package/dist/ops/revisions.d.ts +66 -0
- package/dist/ops/revisions.d.ts.map +1 -0
- package/dist/ops/revisions.js +97 -0
- package/dist/ops/revisions.js.map +1 -0
- package/dist/ops/types.d.ts +49 -1
- package/dist/ops/types.d.ts.map +1 -1
- package/dist/ops/undo.d.ts +23 -2
- package/dist/ops/undo.d.ts.map +1 -1
- package/dist/ops/undo.js +107 -1
- package/dist/ops/undo.js.map +1 -1
- package/dist/ops/withheld.d.ts +37 -0
- package/dist/ops/withheld.d.ts.map +1 -0
- package/dist/ops/withheld.js +84 -0
- package/dist/ops/withheld.js.map +1 -0
- package/dist/permissions/policy.d.ts +15 -0
- package/dist/permissions/policy.d.ts.map +1 -1
- package/dist/permissions/policy.js +28 -1
- package/dist/permissions/policy.js.map +1 -1
- package/dist/permissions/sight.d.ts +50 -0
- package/dist/permissions/sight.d.ts.map +1 -0
- package/dist/permissions/sight.js +76 -0
- package/dist/permissions/sight.js.map +1 -0
- package/dist/permissions/types.d.ts +26 -0
- package/dist/permissions/types.d.ts.map +1 -1
- package/dist/permissions/types.js.map +1 -1
- package/dist/persistence/memory.d.ts.map +1 -1
- package/dist/persistence/memory.js +25 -0
- package/dist/persistence/memory.js.map +1 -1
- package/dist/persistence/sql.d.ts +43 -0
- package/dist/persistence/sql.d.ts.map +1 -0
- package/dist/persistence/sql.js +154 -0
- package/dist/persistence/sql.js.map +1 -0
- package/dist/persistence/sqlite.d.ts +17 -3
- package/dist/persistence/sqlite.d.ts.map +1 -1
- package/dist/persistence/sqlite.js +32 -96
- package/dist/persistence/sqlite.js.map +1 -1
- package/dist/persistence/types.d.ts +19 -0
- package/dist/persistence/types.d.ts.map +1 -1
- package/dist/presence.d.ts +31 -0
- package/dist/presence.d.ts.map +1 -1
- package/dist/presence.js +36 -0
- package/dist/presence.js.map +1 -1
- package/dist/scaffold/from-template.d.ts +16 -0
- package/dist/scaffold/from-template.d.ts.map +1 -0
- package/dist/scaffold/from-template.js +157 -0
- package/dist/scaffold/from-template.js.map +1 -0
- package/dist/scaffold/index.d.ts +10 -1
- package/dist/scaffold/index.d.ts.map +1 -1
- package/dist/scaffold/index.js +35 -7
- package/dist/scaffold/index.js.map +1 -1
- package/dist/scaffold/names.d.ts +4 -0
- package/dist/scaffold/names.d.ts.map +1 -1
- package/dist/scaffold/names.js.map +1 -1
- package/dist/scaffold/project.d.ts +1 -1
- package/dist/scaffold/project.d.ts.map +1 -1
- package/dist/scaffold/project.js +44 -13
- package/dist/scaffold/project.js.map +1 -1
- package/dist/scaffold/ui.d.ts.map +1 -1
- package/dist/scaffold/ui.js +19 -10
- package/dist/scaffold/ui.js.map +1 -1
- package/dist/schema/define-node.d.ts +20 -0
- package/dist/schema/define-node.d.ts.map +1 -1
- package/dist/schema/define-node.js +27 -2
- package/dist/schema/define-node.js.map +1 -1
- package/dist/schema/path.d.ts +19 -0
- package/dist/schema/path.d.ts.map +1 -0
- package/dist/schema/path.js +34 -0
- package/dist/schema/path.js.map +1 -0
- package/dist/schema/types.d.ts +6 -0
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/seen.d.ts +58 -0
- package/dist/seen.d.ts.map +1 -0
- package/dist/seen.js +194 -0
- package/dist/seen.js.map +1 -0
- package/dist/store.d.ts +317 -8
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +720 -37
- package/dist/store.js.map +1 -1
- package/dist/testing.d.ts +6 -0
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +3 -1
- package/dist/testing.js.map +1 -1
- package/dist/theme/palettes.d.ts.map +1 -1
- package/dist/theme/palettes.js +4 -0
- package/dist/theme/palettes.js.map +1 -1
- package/dist/theme/types.d.ts +9 -0
- package/dist/theme/types.d.ts.map +1 -1
- package/dist/theme/types.js +4 -0
- package/dist/theme/types.js.map +1 -1
- package/dist/validate-graph.d.ts +83 -0
- package/dist/validate-graph.d.ts.map +1 -0
- package/dist/validate-graph.js +288 -0
- package/dist/validate-graph.js.map +1 -0
- package/dist/version.d.ts +3 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +3 -0
- package/dist/version.js.map +1 -0
- package/dist/views/types.d.ts +8 -0
- package/dist/views/types.d.ts.map +1 -1
- package/dist/views/types.js +5 -0
- package/dist/views/types.js.map +1 -1
- package/dist/watched.d.ts +39 -0
- package/dist/watched.d.ts.map +1 -1
- package/dist/watched.js +94 -1
- package/dist/watched.js.map +1 -1
- package/dist/who.d.ts +24 -1
- package/dist/who.d.ts.map +1 -1
- package/dist/who.js +49 -2
- package/dist/who.js.map +1 -1
- package/package.json +9 -1
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { createSqlAdapter } from "./sql.js";
|
|
2
|
+
export { createSqlAdapter } from "./sql.js";
|
|
1
3
|
/**
|
|
2
4
|
* The Drizzle/SQLite table shapes this adapter reads and writes, for an app
|
|
3
5
|
* that wants to declare them in its own Drizzle schema:
|
|
@@ -25,107 +27,41 @@ export const SQLITE_TABLE_SHAPE = {
|
|
|
25
27
|
};
|
|
26
28
|
/**
|
|
27
29
|
* Reads and writes an app's existing `graph_nodes` / `graph_edges` tables —
|
|
28
|
-
* the shape the household example already stores
|
|
29
|
-
*
|
|
30
|
-
*
|
|
30
|
+
* the shape the household example already stores — through better-sqlite3.
|
|
31
|
+
* The SQL adapter over `sqlFromDatabase(database)`: one implementation, so
|
|
32
|
+
* what holds here holds over a Durable Object's storage too (FR-09).
|
|
31
33
|
*/
|
|
32
34
|
export function createSqliteAdapter(options) {
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
PRIMARY KEY (${scope}, position)
|
|
49
|
-
);
|
|
50
|
-
CREATE TABLE IF NOT EXISTS ${opTable} (
|
|
51
|
-
${scope} TEXT NOT NULL, seq INTEGER NOT NULL, data TEXT NOT NULL,
|
|
52
|
-
PRIMARY KEY (${scope}, seq)
|
|
53
|
-
);
|
|
54
|
-
`);
|
|
55
|
-
}
|
|
56
|
-
const selectNodes = db.prepare(`SELECT id, kind, data FROM ${nodeTable} WHERE ${scope} = ?`);
|
|
57
|
-
const selectEdges = db.prepare(`SELECT kind, from_id, to_id FROM ${edgeTable} WHERE ${scope} = ? ORDER BY position ASC`);
|
|
58
|
-
const deleteNodes = db.prepare(`DELETE FROM ${nodeTable} WHERE ${scope} = ?`);
|
|
59
|
-
const deleteEdges = db.prepare(`DELETE FROM ${edgeTable} WHERE ${scope} = ?`);
|
|
60
|
-
const insertNode = db.prepare(`INSERT INTO ${nodeTable} (${scope}, id, kind, data) VALUES (?, ?, ?, ?)`);
|
|
61
|
-
const insertEdge = db.prepare(`INSERT INTO ${edgeTable} (${scope}, position, kind, from_id, to_id) VALUES (?, ?, ?, ?, ?)`);
|
|
62
|
-
/**
|
|
63
|
-
* The op table is the framework's own, not the app's, so it is created on
|
|
64
|
-
* demand. The node and edge tables are the app's and are never touched
|
|
65
|
-
* unless `createTables` explicitly asks for them.
|
|
66
|
-
*/
|
|
67
|
-
let opTableReady = false;
|
|
68
|
-
function ensureOpTable() {
|
|
69
|
-
if (opTableReady)
|
|
70
|
-
return;
|
|
71
|
-
db.exec(`CREATE TABLE IF NOT EXISTS ${opTable} (
|
|
72
|
-
${scope} TEXT NOT NULL, seq INTEGER NOT NULL, data TEXT NOT NULL,
|
|
73
|
-
PRIMARY KEY (${scope}, seq)
|
|
74
|
-
)`);
|
|
75
|
-
opTableReady = true;
|
|
76
|
-
}
|
|
77
|
-
const write = db.transaction(((key, snapshot) => {
|
|
78
|
-
deleteEdges.run(key);
|
|
79
|
-
deleteNodes.run(key);
|
|
80
|
-
for (const node of snapshot.nodes) {
|
|
81
|
-
insertNode.run(key, node.id, node.kind, JSON.stringify(node));
|
|
35
|
+
const { database, ...tables } = options;
|
|
36
|
+
return createSqlAdapter({ ...sqlFromDatabase(database), ...tables });
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* better-sqlite3 as the SQL adapter's `exec`, with its own transaction.
|
|
40
|
+
* Each statement is prepared once and kept, and a statement that reads
|
|
41
|
+
* nothing is `run` rather than asked for rows (better-sqlite3 refuses that).
|
|
42
|
+
*/
|
|
43
|
+
export function sqlFromDatabase(database) {
|
|
44
|
+
const prepared = new Map();
|
|
45
|
+
const statement = (sql) => {
|
|
46
|
+
let found = prepared.get(sql);
|
|
47
|
+
if (!found) {
|
|
48
|
+
found = database.prepare(sql);
|
|
49
|
+
prepared.set(sql, found);
|
|
82
50
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
});
|
|
86
|
-
}));
|
|
51
|
+
return found;
|
|
52
|
+
};
|
|
87
53
|
return {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
// columns win so a row is never internally inconsistent.
|
|
98
|
-
return { ...parsed, id: row.id, kind: row.kind };
|
|
99
|
-
});
|
|
100
|
-
const edges = edgeRows.map((row) => ({
|
|
101
|
-
kind: row.kind,
|
|
102
|
-
from: row.from_id,
|
|
103
|
-
to: row.to_id,
|
|
104
|
-
}));
|
|
105
|
-
return { nodes, edges };
|
|
106
|
-
},
|
|
107
|
-
async save(key, snapshot) {
|
|
108
|
-
write(key, snapshot);
|
|
109
|
-
},
|
|
110
|
-
async delete(key) {
|
|
111
|
-
deleteEdges.run(key);
|
|
112
|
-
deleteNodes.run(key);
|
|
113
|
-
},
|
|
114
|
-
async loadLog(key) {
|
|
115
|
-
ensureOpTable();
|
|
116
|
-
const rows = db
|
|
117
|
-
.prepare(`SELECT data FROM ${opTable} WHERE ${scope} = ? ORDER BY seq ASC`)
|
|
118
|
-
.all(key);
|
|
119
|
-
return rows.map((row) => JSON.parse(row.data));
|
|
120
|
-
},
|
|
121
|
-
async appendOps(key, ops) {
|
|
122
|
-
if (ops.length === 0)
|
|
123
|
-
return;
|
|
124
|
-
ensureOpTable();
|
|
125
|
-
const insert = db.prepare(`INSERT OR REPLACE INTO ${opTable} (${scope}, seq, data) VALUES (?, ?, ?)`);
|
|
126
|
-
for (const op of ops)
|
|
127
|
-
insert.run(key, op.seq, JSON.stringify(op));
|
|
54
|
+
sql: {
|
|
55
|
+
exec(sql, ...params) {
|
|
56
|
+
const prepared = statement(sql);
|
|
57
|
+
const reads = prepared.reader ?? /^\s*(SELECT|WITH|PRAGMA|VALUES)\b/i.test(sql);
|
|
58
|
+
if (reads)
|
|
59
|
+
return prepared.all(...params);
|
|
60
|
+
prepared.run(...params);
|
|
61
|
+
return [];
|
|
62
|
+
},
|
|
128
63
|
},
|
|
64
|
+
transaction: (fn) => database.transaction(fn)(),
|
|
129
65
|
};
|
|
130
66
|
}
|
|
131
67
|
//# sourceMappingURL=sqlite.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../../src/persistence/sqlite.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../../src/persistence/sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAgB,MAAM,UAAU,CAAC;AAG1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAgC5C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,KAAK,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC;IACtC,KAAK,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC;CAChD,CAAC;AAEX;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAA6B;IAC/D,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC;IACxC,OAAO,gBAAgB,CAAC,EAAE,GAAG,eAAe,CAAC,QAAQ,CAAC,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;AACvE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,QAAwB;IACtD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA2B,CAAC;IACpD,MAAM,SAAS,GAAG,CAAC,GAAW,EAAmB,EAAE;QACjD,IAAI,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAC9B,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC3B,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;IACF,OAAO;QACL,GAAG,EAAE;YACH,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM;gBACjB,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;gBAChC,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,IAAI,oCAAoC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBAChF,IAAI,KAAK;oBAAE,OAAO,QAAQ,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC;gBAC1C,QAAQ,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC;gBACxB,OAAO,EAAE,CAAC;YACZ,CAAC;SACF;QACD,WAAW,EAAE,CAAI,EAAW,EAAK,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAa,CAAC,EAAO;KAC/E,CAAC;AACJ,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { GraphSnapshot } from "../graph/types.js";
|
|
2
|
+
import type { Epoch, LogArchive } from "../ops/log.js";
|
|
2
3
|
import type { Operation } from "../ops/types.js";
|
|
3
4
|
/**
|
|
4
5
|
* The framework owns the reactive graph, invariants, diff and undo;
|
|
@@ -18,5 +19,23 @@ export interface PersistenceAdapter<Scope = string> {
|
|
|
18
19
|
/** Optional: adapters that keep history append the log too. */
|
|
19
20
|
loadLog?(scope: Scope): Promise<Operation[]>;
|
|
20
21
|
appendOps?(scope: Scope, ops: readonly Operation[]): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Optional: the epochs the log folds from (FR-27), kept beside it. An
|
|
24
|
+
* adapter without them reopens a store with none recorded, and ship has
|
|
25
|
+
* it adopt what it holds as its first epoch on each open.
|
|
26
|
+
*/
|
|
27
|
+
loadEpochs?(scope: Scope): Promise<Epoch[]>;
|
|
28
|
+
saveEpochs?(scope: Scope, epochs: readonly Epoch[]): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Optional (FR-23): compaction behind an undo horizon. Moves the ops
|
|
31
|
+
* before `checkpoint.seq`, and the epochs before it, into the archive,
|
|
32
|
+
* and makes `checkpoint` the first epoch. From then on `loadLog` returns
|
|
33
|
+
* the ops from its seq on and `loadEpochs` the checkpoint and what came
|
|
34
|
+
* after it, so a normal open loads nothing older; `loadArchive` returns
|
|
35
|
+
* what was moved, oldest first, for a full export. Nothing is deleted.
|
|
36
|
+
* An adapter that keeps no epochs keeps no checkpoint, and has neither.
|
|
37
|
+
*/
|
|
38
|
+
compact?(scope: Scope, checkpoint: Epoch): Promise<void>;
|
|
39
|
+
loadArchive?(scope: Scope): Promise<LogArchive>;
|
|
21
40
|
}
|
|
22
41
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/persistence/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD;;;;GAIG;AACH,MAAM,WAAW,kBAAkB,CAAC,KAAK,GAAG,MAAM;IAChD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,IAAI,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAAC;IAClD,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,+DAA+D;IAC/D,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IAC7C,SAAS,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,SAAS,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/persistence/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD;;;;GAIG;AACH,MAAM,WAAW,kBAAkB,CAAC,KAAK,GAAG,MAAM;IAChD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,IAAI,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAAC;IAClD,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,+DAA+D;IAC/D,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IAC7C,SAAS,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,SAAS,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnE;;;;OAIG;IACH,UAAU,CAAC,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IAC5C,UAAU,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,KAAK,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnE;;;;;;;;OAQG;IACH,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,WAAW,CAAC,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CACjD"}
|
package/dist/presence.d.ts
CHANGED
|
@@ -28,6 +28,37 @@ export interface PresenceChannel {
|
|
|
28
28
|
}
|
|
29
29
|
/** How long a presence stands after its last word: three missed heartbeats at the poll's own pace. */
|
|
30
30
|
export declare const PRESENCE_TTL_MS = 2500;
|
|
31
|
+
/**
|
|
32
|
+
* HOW LONG A PRESENCE FROM SOMEWHERE ELSE STANDS (FR-13). A list that came
|
|
33
|
+
* over a wire was stamped by a server's clock and read by a browser's, and
|
|
34
|
+
* it arrives at the poll's pace rather than the heartbeat's, so it is given
|
|
35
|
+
* four times a tab's own grace. Past it a participant is gone whether or
|
|
36
|
+
* not the channel ever said so: a host's channel that forgets to drop
|
|
37
|
+
* somebody does not keep them on the map.
|
|
38
|
+
*/
|
|
39
|
+
export declare const REMOTE_PRESENCE_TTL_MS: number;
|
|
40
|
+
/** The parts of a participant key: who, and which tab of theirs. */
|
|
41
|
+
export interface Participant {
|
|
42
|
+
readonly kind: "human" | "agent" | "rule" | "system";
|
|
43
|
+
readonly id?: string;
|
|
44
|
+
readonly session?: string;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* THE ONE DIALECT. A participant is `kind:id:session`: the op log's own
|
|
48
|
+
* reading of an author (`Author.kind`, `.id`, `.session`), a figure's key on
|
|
49
|
+
* the map, and what the wire's presence routes carry, so a figure and its
|
|
50
|
+
* edits are the same person by construction. A host that says who is here
|
|
51
|
+
* from its own server writes this, and only this.
|
|
52
|
+
*/
|
|
53
|
+
export declare function participantKey(participant: Participant): string;
|
|
54
|
+
/**
|
|
55
|
+
* A participant key read back. The kind is everything before the first
|
|
56
|
+
* colon and the session everything after the last, so an id that holds a
|
|
57
|
+
* colon (`mcp:claude`) survives. Null for anything that is not a key.
|
|
58
|
+
*/
|
|
59
|
+
export declare function parseParticipant(key: string): (Participant & {
|
|
60
|
+
readonly session: string;
|
|
61
|
+
}) | null;
|
|
31
62
|
/**
|
|
32
63
|
* The others as they are now: what arrived, minus what has gone quiet, minus
|
|
33
64
|
* yourself. Pure, so a test can ask what a viewer sees without a channel.
|
package/dist/presence.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"presence.d.ts","sourceRoot":"","sources":["../src/presence.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,aAAa;IAC5B,gFAAgF;IAChF,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,QAAQ;IACvB,kGAAkG;IAClG,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,2FAA2F;IAC3F,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,0DAA0D;IAC1D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,iEAAiE;IACjE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,sDAAsD;IACtD,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC;IAC/B,mCAAmC;IACnC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,wEAAwE;IACxE,IAAI,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC/B,yFAAyF;IACzF,KAAK,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,SAAS,QAAQ,EAAE,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IAChE,mCAAmC;IACnC,KAAK,IAAI,IAAI,CAAC;CACf;AAED,sGAAsG;AACtG,eAAO,MAAM,eAAe,OAAO,CAAC;AAEpC;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,QAAQ,CAAC,EACpC,OAAO,EAAE,SAAS,QAAQ,EAAE,EAC5B,GAAG,EAAE,MAAM,EACX,KAAK,GAAE,MAAwB,EAC/B,IAAI,CAAC,EAAE,MAAM,GACZ,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAevB;AAED,uEAAuE;AACvE,wBAAgB,YAAY,CAAC,CAAC,EAAE,QAAQ,GAAG,SAAS,EAAE,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,OAAO,CAWtF"}
|
|
1
|
+
{"version":3,"file":"presence.d.ts","sourceRoot":"","sources":["../src/presence.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,aAAa;IAC5B,gFAAgF;IAChF,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,QAAQ;IACvB,kGAAkG;IAClG,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,2FAA2F;IAC3F,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,0DAA0D;IAC1D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,iEAAiE;IACjE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,sDAAsD;IACtD,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC;IAC/B,mCAAmC;IACnC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,wEAAwE;IACxE,IAAI,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC/B,yFAAyF;IACzF,KAAK,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,SAAS,QAAQ,EAAE,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IAChE,mCAAmC;IACnC,KAAK,IAAI,IAAI,CAAC;CACf;AAED,sGAAsG;AACtG,eAAO,MAAM,eAAe,OAAO,CAAC;AAEpC;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,QAAsB,CAAC;AAE1D,oEAAoE;AACpE,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;IACrD,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAID;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,WAAW,GAAG,MAAM,CAE/D;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,WAAW,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,IAAI,CAQjG;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,QAAQ,CAAC,EACpC,OAAO,EAAE,SAAS,QAAQ,EAAE,EAC5B,GAAG,EAAE,MAAM,EACX,KAAK,GAAE,MAAwB,EAC/B,IAAI,CAAC,EAAE,MAAM,GACZ,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAevB;AAED,uEAAuE;AACvE,wBAAgB,YAAY,CAAC,CAAC,EAAE,QAAQ,GAAG,SAAS,EAAE,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,OAAO,CAWtF"}
|
package/dist/presence.js
CHANGED
|
@@ -12,6 +12,42 @@
|
|
|
12
12
|
*/
|
|
13
13
|
/** How long a presence stands after its last word: three missed heartbeats at the poll's own pace. */
|
|
14
14
|
export const PRESENCE_TTL_MS = 2500;
|
|
15
|
+
/**
|
|
16
|
+
* HOW LONG A PRESENCE FROM SOMEWHERE ELSE STANDS (FR-13). A list that came
|
|
17
|
+
* over a wire was stamped by a server's clock and read by a browser's, and
|
|
18
|
+
* it arrives at the poll's pace rather than the heartbeat's, so it is given
|
|
19
|
+
* four times a tab's own grace. Past it a participant is gone whether or
|
|
20
|
+
* not the channel ever said so: a host's channel that forgets to drop
|
|
21
|
+
* somebody does not keep them on the map.
|
|
22
|
+
*/
|
|
23
|
+
export const REMOTE_PRESENCE_TTL_MS = PRESENCE_TTL_MS * 4;
|
|
24
|
+
const PARTICIPANT_KINDS = new Set(["human", "agent", "rule", "system"]);
|
|
25
|
+
/**
|
|
26
|
+
* THE ONE DIALECT. A participant is `kind:id:session`: the op log's own
|
|
27
|
+
* reading of an author (`Author.kind`, `.id`, `.session`), a figure's key on
|
|
28
|
+
* the map, and what the wire's presence routes carry, so a figure and its
|
|
29
|
+
* edits are the same person by construction. A host that says who is here
|
|
30
|
+
* from its own server writes this, and only this.
|
|
31
|
+
*/
|
|
32
|
+
export function participantKey(participant) {
|
|
33
|
+
return `${participant.kind}:${participant.id ?? ""}:${participant.session ?? ""}`;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* A participant key read back. The kind is everything before the first
|
|
37
|
+
* colon and the session everything after the last, so an id that holds a
|
|
38
|
+
* colon (`mcp:claude`) survives. Null for anything that is not a key.
|
|
39
|
+
*/
|
|
40
|
+
export function parseParticipant(key) {
|
|
41
|
+
const first = key.indexOf(":");
|
|
42
|
+
const last = key.lastIndexOf(":");
|
|
43
|
+
if (first < 0 || last === first)
|
|
44
|
+
return null;
|
|
45
|
+
const kind = key.slice(0, first);
|
|
46
|
+
if (!PARTICIPANT_KINDS.has(kind))
|
|
47
|
+
return null;
|
|
48
|
+
const id = key.slice(first + 1, last);
|
|
49
|
+
return { kind: kind, ...(id ? { id } : {}), session: key.slice(last + 1) };
|
|
50
|
+
}
|
|
15
51
|
/**
|
|
16
52
|
* The others as they are now: what arrived, minus what has gone quiet, minus
|
|
17
53
|
* yourself. Pure, so a test can ask what a viewer sees without a channel.
|
package/dist/presence.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"presence.js","sourceRoot":"","sources":["../src/presence.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAiCH,sGAAsG;AACtG,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CAAC;AAEpC;;;GAGG;AACH,MAAM,UAAU,YAAY,CAC1B,KAAoC,EACpC,OAA4B,EAC5B,GAAW,EACX,QAAgB,eAAe,EAC/B,IAAa;IAEb,MAAM,IAAI,GAAG,IAAI,GAAG,EAAoB,CAAC;IACzC,KAAK,MAAM,CAAC,WAAW,EAAE,QAAQ,CAAC,IAAI,KAAK,EAAE,CAAC;QAC5C,IAAI,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,KAAK;YAAE,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IAC7E,CAAC;IACD,KAAK,MAAM,QAAQ,IAAI,OAAO,EAAE,CAAC;QAC/B,IAAI,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC;YAC3C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;YAClC,SAAS;QACX,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;QAC5C,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;YAAE,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IACxG,CAAC;IACD,IAAI,IAAI,KAAK,SAAS;QAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC1C,OAAO,IAAI,CAAC;AACd,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,YAAY,CAAC,CAAuB,EAAE,CAAuB;IAC3E,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;QAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IAC7B,OAAO,CACL,CAAC,CAAC,WAAW,KAAK,CAAC,CAAC,WAAW;QAC/B,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI;QACjB,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG;QACf,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI;QACjB,CAAC,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC;QACrC,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,IAAI,IAAI,CAAC;QAC/C,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,IAAI,IAAI,CAAC,CACpD,CAAC;AACJ,CAAC"}
|
|
1
|
+
{"version":3,"file":"presence.js","sourceRoot":"","sources":["../src/presence.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { GraviewTemplate } from "../document/graview-template.js";
|
|
2
|
+
import { type Ids } from "./names.js";
|
|
3
|
+
/** The kind a project's UI leads with, and the act its seat is gated on: the first kind something creates. */
|
|
4
|
+
export declare function templateKind(template: GraviewTemplate): {
|
|
5
|
+
readonly kind: string;
|
|
6
|
+
readonly plural: string;
|
|
7
|
+
readonly gate: string;
|
|
8
|
+
};
|
|
9
|
+
export declare function documentJson(template: GraviewTemplate): string;
|
|
10
|
+
export declare function templateJson(template: GraviewTemplate): string;
|
|
11
|
+
export declare function documentAppTs(ids: Ids): string;
|
|
12
|
+
export declare function documentSchemaTs(ids: Ids): string;
|
|
13
|
+
export declare function documentBrandTs(ids: Ids): string;
|
|
14
|
+
export declare function documentTest(ids: Ids): string;
|
|
15
|
+
export declare function documentReadmeLayout(ids: Ids, run: string): string;
|
|
16
|
+
//# sourceMappingURL=from-template.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"from-template.d.ts","sourceRoot":"","sources":["../../src/scaffold/from-template.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,EAAE,KAAK,GAAG,EAAyB,MAAM,YAAY,CAAC;AAmB7D,8GAA8G;AAC9G,wBAAgB,YAAY,CAAC,QAAQ,EAAE,eAAe,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAQjI;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,CAE9D;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,CAE9D;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,CAkC9C;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,CAOjD;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,CAiBhD;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,CA+C7C;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAalE"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { escapeString, slugify } from "./names.js";
|
|
2
|
+
/*
|
|
3
|
+
* A PROJECT FROM A TEMPLATE (FR-08): the same checkout `graview create`
|
|
4
|
+
* always writes, with the declaration KEPT AS THE DOCUMENT.
|
|
5
|
+
*
|
|
6
|
+
* `src/domain/app.json` is the template's document, and `src/domain/app.ts`
|
|
7
|
+
* compiles it with `compileDocument` when the domain loads. The other choice
|
|
8
|
+
* — writing TypeScript from the document — would need a generator for every
|
|
9
|
+
* construct the document has (expression rules, effects, guards, refusal
|
|
10
|
+
* sentences, view specs) and would then be a second declaration that could
|
|
11
|
+
* drift from the first. Kept as the document, the project IS the template's
|
|
12
|
+
* app: `graview describe` says the same of both by construction, the studio
|
|
13
|
+
* and `editDocument` change it as data, and a template shared back out is the
|
|
14
|
+
* file as it stands. The UI, the tests, the CI and the scripts are the ones
|
|
15
|
+
* every project gets; the template itself sits at the root as
|
|
16
|
+
* `template.json`, for `graview apply --template` to set a store up from.
|
|
17
|
+
*/
|
|
18
|
+
/** The kind a project's UI leads with, and the act its seat is gated on: the first kind something creates. */
|
|
19
|
+
export function templateKind(template) {
|
|
20
|
+
const document = template.document;
|
|
21
|
+
const kinds = Object.keys(document.kinds ?? {});
|
|
22
|
+
const acts = Object.entries(document.acts ?? {});
|
|
23
|
+
const creating = kinds.map((kind) => [kind, acts.find(([, act]) => act.creates === kind)?.[0]]).find(([, act]) => act !== undefined);
|
|
24
|
+
const kind = creating?.[0] ?? kinds[0] ?? "item";
|
|
25
|
+
const plural = slugify(document.kinds?.[kind]?.plural ?? `${kind}s`) || `${kind}s`;
|
|
26
|
+
return { kind, plural, gate: creating?.[1] ?? acts[0]?.[0] ?? `add-${kind}` };
|
|
27
|
+
}
|
|
28
|
+
export function documentJson(template) {
|
|
29
|
+
return `${JSON.stringify(template.document, null, 2)}\n`;
|
|
30
|
+
}
|
|
31
|
+
export function templateJson(template) {
|
|
32
|
+
return `${JSON.stringify(template, null, 2)}\n`;
|
|
33
|
+
}
|
|
34
|
+
export function documentAppTs(ids) {
|
|
35
|
+
return `import { Store, type AnySchema, type GraviewApp, type StoreOptions } from "@graview/core";
|
|
36
|
+
import { compileDocument, sayFindings } from "@graview/core/document";
|
|
37
|
+
import document from "./app.json" with { type: "json" };
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* THE DECLARATION IS A DOCUMENT: app.json, compiled when this module loads.
|
|
41
|
+
* It runs no code of its own, so it is the same app here, in a host that
|
|
42
|
+
* accepts documents from strangers, and in the template it came from.
|
|
43
|
+
* \`graview check\` and \`graview describe\` read it through this module or
|
|
44
|
+
* straight from the file; edit it, or open it in the studio, and the
|
|
45
|
+
* compiler says what is wrong with the JSON path to fix it at.
|
|
46
|
+
*/
|
|
47
|
+
const compiled = compileDocument(document);
|
|
48
|
+
if (!compiled.ok) {
|
|
49
|
+
throw new Error(\`src/domain/app.json does not compile:\\n\${sayFindings(compiled.findings)}\`);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export const ${ids.appVar}: GraviewApp = compiled.app;
|
|
53
|
+
|
|
54
|
+
export type ${ids.StoreType} = Store<AnySchema>;
|
|
55
|
+
|
|
56
|
+
export function createStore(options: Partial<StoreOptions<AnySchema>> = {}): ${ids.StoreType} {
|
|
57
|
+
return new Store<AnySchema>({
|
|
58
|
+
schema: ${ids.appVar}.schema,
|
|
59
|
+
mutations: ${ids.appVar}.mutations ?? [],
|
|
60
|
+
invariants: ${ids.appVar}.invariants ?? [],
|
|
61
|
+
...(${ids.appVar}.policy ? { policy: ${ids.appVar}.policy } : {}),
|
|
62
|
+
...options,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export default ${ids.appVar};
|
|
67
|
+
`;
|
|
68
|
+
}
|
|
69
|
+
export function documentSchemaTs(ids) {
|
|
70
|
+
return `import { ${ids.appVar} } from "./app.js";
|
|
71
|
+
|
|
72
|
+
/** The schema the document compiles to, under the name the UI imports it by. */
|
|
73
|
+
export const ${ids.schemaVar} = ${ids.appVar}.schema;
|
|
74
|
+
export type ${ids.SchemaType} = typeof ${ids.schemaVar};
|
|
75
|
+
`;
|
|
76
|
+
}
|
|
77
|
+
export function documentBrandTs(ids) {
|
|
78
|
+
return `import { brandFromAccent, DARK, LIGHT, type Brand } from "@graview/core";
|
|
79
|
+
import { ${ids.appVar} } from "./app.js";
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* The document's brand when it declares one (\`brand.accent\` in app.json);
|
|
83
|
+
* otherwise both schemes derived from one accent, measured against AA.
|
|
84
|
+
*/
|
|
85
|
+
function brandOf(): Brand {
|
|
86
|
+
if (${ids.appVar}.brand) return ${ids.appVar}.brand;
|
|
87
|
+
const derived = brandFromAccent({ accent: "${ids.accent}", base: { dark: DARK, light: LIGHT } });
|
|
88
|
+
if (!derived.ok) throw new Error(\`${escapeString(ids.name)} cannot be derived from ${ids.accent}: \${derived.why}\`);
|
|
89
|
+
return { name: ${ids.appVar}.name, schemes: derived.schemes };
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export const ${ids.brandVar}: Brand = brandOf();
|
|
93
|
+
`;
|
|
94
|
+
}
|
|
95
|
+
export function documentTest(ids) {
|
|
96
|
+
return `import { checkApp, type Principal } from "@graview/core";
|
|
97
|
+
import { instantiateTemplate } from "@graview/core/document";
|
|
98
|
+
import { describe, expect, it } from "vitest";
|
|
99
|
+
import template from "../template.json" with { type: "json" };
|
|
100
|
+
import document from "../src/domain/app.json" with { type: "json" };
|
|
101
|
+
import { ${ids.appVar}, createStore } from "../src/domain/app.js";
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* The domain tier has no DOM in it, so these run headless. The declaration
|
|
105
|
+
* is the template's document until you change it; the setup test holds the
|
|
106
|
+
* template's own acts to the document as it stands.
|
|
107
|
+
*/
|
|
108
|
+
|
|
109
|
+
describe("the declaration", () => {
|
|
110
|
+
it("passes its own check", () => {
|
|
111
|
+
const result = checkApp(${ids.appVar});
|
|
112
|
+
expect(result.findings.filter((f) => f.severity === "error")).toEqual([]);
|
|
113
|
+
expect(result.ok).toBe(true);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it("compiles from the document it keeps", () => {
|
|
117
|
+
expect(${ids.appVar}.name).toBe(document.name);
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
describe("the template's setup", () => {
|
|
122
|
+
const setUp = () => {
|
|
123
|
+
const made = instantiateTemplate({ ...template, document });
|
|
124
|
+
if (!made.ok) throw new Error(made.findings.map((f) => \`\${f.path}: \${f.message}\`).join("\\n"));
|
|
125
|
+
return made;
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
it("runs as one batch, and one undo takes it back", () => {
|
|
129
|
+
const store = createStore();
|
|
130
|
+
const author: Principal = { kind: "system", id: "template:${escapeString(ids.packageName)}" };
|
|
131
|
+
const calls = setUp().setup;
|
|
132
|
+
if (calls.length === 0) return;
|
|
133
|
+
for (const call of calls) {
|
|
134
|
+
store.apply({ name: call.name, args: call.args }, { author, batch: "setup", intent: call.intent });
|
|
135
|
+
}
|
|
136
|
+
expect(new Set(store.log.all().map((op) => op.batch))).toEqual(new Set(["setup"]));
|
|
137
|
+
store.undo("setup", { author });
|
|
138
|
+
expect(store.graph.allNodes()).toEqual([]);
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
`;
|
|
142
|
+
}
|
|
143
|
+
export function documentReadmeLayout(ids, run) {
|
|
144
|
+
return `src/domain/ the declaration — no React in here; this is what graview check reads
|
|
145
|
+
app.json the declaration document: kinds, acts, rules, policy, brand, views
|
|
146
|
+
app.ts compiles app.json with compileDocument; createStore
|
|
147
|
+
schema.ts the compiled schema, under the name the UI imports
|
|
148
|
+
brand.ts the document's brand, or one derived from an accent
|
|
149
|
+
src/ui/
|
|
150
|
+
views.tsx registerDefaultViews, then your own where the generic one is wrong
|
|
151
|
+
app.tsx the provider, the Shell primitive, and a seat — under sixty lines
|
|
152
|
+
pages.tsx the ${ids.kind}'s page on the routed face, in your words, over the derived ones
|
|
153
|
+
src/main.tsx the theme, the store that remembers, the two faces
|
|
154
|
+
template.json the template this project was made from: \`${run} apply-template\` sets a store up from it
|
|
155
|
+
tests/ the declaration checks clean, and the template's setup runs as one undoable batch`;
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=from-template.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"from-template.js","sourceRoot":"","sources":["../../src/scaffold/from-template.ts"],"names":[],"mappings":"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"}
|
package/dist/scaffold/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { GraviewTemplate } from "../document/graview-template.js";
|
|
1
2
|
export { pascal, slugify, titleCase, validateScaffoldOptions } from "./names.js";
|
|
2
3
|
export { GRAVIEW_PACKAGES, LINKED_PACKAGES } from "./project.js";
|
|
3
4
|
export interface ScaffoldOptions {
|
|
@@ -47,6 +48,14 @@ export interface ScaffoldOptions {
|
|
|
47
48
|
* Two is a gap rather than a taste.
|
|
48
49
|
*/
|
|
49
50
|
readonly workspace?: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* A template made anywhere — Graview Cloud's shape (FR-08). The project
|
|
53
|
+
* keeps its document as the declaration (`src/domain/app.json`, compiled
|
|
54
|
+
* when the domain loads) and the template beside it as `template.json`,
|
|
55
|
+
* for `graview apply --template` to set a store up from. Read it with
|
|
56
|
+
* `readGraviewTemplate` first; this trusts what it is handed.
|
|
57
|
+
*/
|
|
58
|
+
readonly template?: GraviewTemplate;
|
|
50
59
|
}
|
|
51
60
|
export interface ScaffoldFile {
|
|
52
61
|
readonly path: string;
|
|
@@ -62,5 +71,5 @@ export interface Scaffold {
|
|
|
62
71
|
readonly port: number;
|
|
63
72
|
readonly linked: boolean;
|
|
64
73
|
}
|
|
65
|
-
export declare function scaffoldProject(
|
|
74
|
+
export declare function scaffoldProject(given: ScaffoldOptions): Scaffold;
|
|
66
75
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scaffold/index.ts"],"names":[],"mappings":"AAmCA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AACjF,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEjE,MAAM,WAAW,eAAe;IAC9B,mEAAmE;IACnE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,kEAAkE;IAClE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,2EAA2E;IAC3E,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,2DAA2D;IAC3D,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,iEAAiE;IACjE,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACzC,6BAA6B;IAC7B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,yCAAyC;IACzC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scaffold/index.ts"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAEvE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AACjF,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEjE,MAAM,WAAW,eAAe;IAC9B,mEAAmE;IACnE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,kEAAkE;IAClE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,2EAA2E;IAC3E,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,2DAA2D;IAC3D,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,iEAAiE;IACjE,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACzC,6BAA6B;IAC7B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,yCAAyC;IACzC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B;;;;;;OAMG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,eAAe,CAAC;CACrC;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;IACxC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,KAAK,CAAC;IACxC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B;AAID,wBAAgB,eAAe,CAAC,KAAK,EAAE,eAAe,GAAG,QAAQ,CAyJhE"}
|
package/dist/scaffold/index.js
CHANGED
|
@@ -17,15 +17,26 @@ import { slugify, titleCase, camel, pascal, validateScaffoldOptions } from "./na
|
|
|
17
17
|
import { SURVEY_SAYS, AUDIT_SAYS, A11Y_SAYS, harness, workspaceRoot, tsconfigBase, rootVitest, packageJson, tsconfig, tsconfigBuild, viteConfig, gitignore, readme, ciYml, } from "./project.js";
|
|
18
18
|
import { schemaTs, mutationsTs, invariantsTs, brandTs, appTs, domainTest } from "./domain.js";
|
|
19
19
|
import { indexHtml, embedHtml, embedTsx, viewsTsx, uiAppTsx, pagesTsx, mainTsx } from "./ui.js";
|
|
20
|
+
import { documentAppTs, documentBrandTs, documentJson, documentSchemaTs, documentTest, templateJson, templateKind } from "./from-template.js";
|
|
20
21
|
export { pascal, slugify, titleCase, validateScaffoldOptions } from "./names.js";
|
|
21
22
|
export { GRAVIEW_PACKAGES, LINKED_PACKAGES } from "./project.js";
|
|
22
|
-
export function scaffoldProject(
|
|
23
|
+
export function scaffoldProject(given) {
|
|
24
|
+
/*
|
|
25
|
+
* FROM A TEMPLATE, the kind the UI leads with is the template's first kind
|
|
26
|
+
* that something creates, and its seat is gated on that act — unless the
|
|
27
|
+
* caller named a kind of the document's itself.
|
|
28
|
+
*/
|
|
29
|
+
const led = given.template ? templateKind(given.template) : undefined;
|
|
30
|
+
const options = led
|
|
31
|
+
? { ...given, kind: given.kind ?? led.kind, plural: given.plural ?? (given.kind === undefined ? led.plural : `${given.kind}s`) }
|
|
32
|
+
: given;
|
|
23
33
|
const problems = validateScaffoldOptions(options);
|
|
24
34
|
if (problems.length > 0)
|
|
25
35
|
throw new Error(problems.join("\n"));
|
|
26
36
|
const name = options.name.trim();
|
|
27
37
|
const kind = options.kind ?? "item";
|
|
28
38
|
const plural = options.plural ?? `${kind}s`;
|
|
39
|
+
const template = options.template;
|
|
29
40
|
const packageName = options.packageName ?? slugify(name);
|
|
30
41
|
const packageManager = options.packageManager ?? "pnpm";
|
|
31
42
|
const port = options.port ?? 5170;
|
|
@@ -77,7 +88,27 @@ export function scaffoldProject(options) {
|
|
|
77
88
|
range,
|
|
78
89
|
packageManager,
|
|
79
90
|
packageName,
|
|
91
|
+
gate: led && given.kind === undefined ? led.gate : `add-${kind}`,
|
|
92
|
+
fromTemplate: template !== undefined,
|
|
80
93
|
};
|
|
94
|
+
/*
|
|
95
|
+
* THE DECLARATION: TypeScript written for one kind, or — from a template —
|
|
96
|
+
* the template's document kept as the document (see ./from-template.ts).
|
|
97
|
+
*/
|
|
98
|
+
const domain = template
|
|
99
|
+
? [
|
|
100
|
+
{ path: "src/domain/app.json", contents: documentJson(template) },
|
|
101
|
+
{ path: "src/domain/app.ts", contents: documentAppTs(ids) },
|
|
102
|
+
{ path: "src/domain/schema.ts", contents: documentSchemaTs(ids) },
|
|
103
|
+
{ path: "src/domain/brand.ts", contents: documentBrandTs(ids) },
|
|
104
|
+
]
|
|
105
|
+
: [
|
|
106
|
+
{ path: "src/domain/schema.ts", contents: schemaTs(ids) },
|
|
107
|
+
{ path: "src/domain/mutations.ts", contents: mutationsTs(ids) },
|
|
108
|
+
{ path: "src/domain/invariants.ts", contents: invariantsTs(ids) },
|
|
109
|
+
{ path: "src/domain/brand.ts", contents: brandTs(ids) },
|
|
110
|
+
{ path: "src/domain/app.ts", contents: appTs(ids) },
|
|
111
|
+
];
|
|
81
112
|
const files = [
|
|
82
113
|
{ path: "package.json", contents: packageJson(ids, workspace) },
|
|
83
114
|
{ path: "tsconfig.json", contents: tsconfig(workspace) },
|
|
@@ -87,18 +118,15 @@ export function scaffoldProject(options) {
|
|
|
87
118
|
{ path: "embed.html", contents: embedHtml(ids) },
|
|
88
119
|
{ path: ".gitignore", contents: gitignore() },
|
|
89
120
|
{ path: "README.md", contents: readme(ids) },
|
|
90
|
-
|
|
91
|
-
{ path: "src/domain/mutations.ts", contents: mutationsTs(ids) },
|
|
92
|
-
{ path: "src/domain/invariants.ts", contents: invariantsTs(ids) },
|
|
93
|
-
{ path: "src/domain/brand.ts", contents: brandTs(ids) },
|
|
94
|
-
{ path: "src/domain/app.ts", contents: appTs(ids) },
|
|
121
|
+
...domain,
|
|
95
122
|
{ path: "src/ui/views.tsx", contents: viewsTsx(ids) },
|
|
96
123
|
{ path: "src/ui/app.tsx", contents: uiAppTsx(ids) },
|
|
97
124
|
{ path: "src/ui/pages.tsx", contents: pagesTsx(ids) },
|
|
98
125
|
{ path: "src/main.tsx", contents: mainTsx(ids) },
|
|
99
126
|
{ path: "src/embed.tsx", contents: embedTsx(ids) },
|
|
100
|
-
{ path: "tests/domain.test.ts", contents: domainTest(ids) },
|
|
127
|
+
{ path: "tests/domain.test.ts", contents: template ? documentTest(ids) : domainTest(ids) },
|
|
101
128
|
{ path: ".github/workflows/ci.yml", contents: ciYml(ids) },
|
|
129
|
+
...(template ? [{ path: "template.json", contents: templateJson(template) }] : []),
|
|
102
130
|
];
|
|
103
131
|
if (!workspace) {
|
|
104
132
|
return { files, name, packageName, kind, plural, packageManager, port, linked: link !== undefined };
|