create-githolon 0.7.0 → 0.7.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-githolon",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
4
4
  "type": "module",
5
5
  "description": "Scaffold a Nomos domain package: the starter domain + compile config + live e2e. `npm create githolon my-app`.",
6
6
  "license": "SEE LICENSE IN LICENSE.md",
@@ -7,12 +7,9 @@
7
7
  */
8
8
  import {
9
9
  z, aggregate, t, Lww, AddWins, directive, create, instance, set, addToSet,
10
- query, count, writeTuple, RelationTuple, relateSubject, relationTuplesByObject,
10
+ query, count, writeTuple, RelationTuple, relationTuplesByObject,
11
11
  } from "@githolon/dsl";
12
12
 
13
- // A todo is open or done. (There is no t.bool() — model a flag as a 2-value Lww enum.)
14
- const DONE = ["open", "done"] as const;
15
-
16
13
  // ── what we store ─────────────────────────────────────────────────────────────
17
14
  export const TodoList = aggregate("TodoList", {
18
15
  title: t.string().merge(Lww), // last writer wins
@@ -21,15 +18,10 @@ export const TodoList = aggregate("TodoList", {
21
18
  export const Todo = aggregate("Todo", {
22
19
  listId: t.string().merge(Lww), // which list this todo is on (the query key)
23
20
  text: t.string().merge(Lww), // last writer wins
24
- done: t.enum(DONE).merge(Lww), // last writer wins
21
+ done: t.bool(), // a flag — Lww by default; reads back a real boolean
25
22
  tags: t.set(t.string()).merge(AddWins), // concurrent taggers UNION — nobody's tag is lost
26
23
  });
27
24
 
28
- // Re-export the framework's Zanzibar tuple aggregate so its events fold into THIS
29
- // chain. relateSubject (an `.ensures(RelationTuple)` directive) is what marks the
30
- // tuple an ensured type, which shareList's tuple write below needs.
31
- export { RelationTuple, relateSubject };
32
-
33
25
  // ── what people do (directives PLAN ops; the sealed engine replays them) ────────
34
26
  export const createList = directive("createList")
35
27
  .creates(TodoList) // Nomos MINTS the id — callers never supply one
@@ -40,7 +32,7 @@ export const addTodo = directive("addTodo")
40
32
  .creates(Todo)
41
33
  .payload(z.object({ listId: z.string().min(1), text: z.string().min(1) }))
42
34
  .plan((p) => {
43
- create(Todo).set("listId", p.listId).set("text", p.text).set("done", "open");
35
+ create(Todo).set("listId", p.listId).set("text", p.text).set("done", false);
44
36
  return [];
45
37
  });
46
38
 
@@ -49,11 +41,11 @@ export const renameTodo = directive("renameTodo")
49
41
  .payload(z.object({ todoId: z.string(), text: z.string().min(1) }))
50
42
  .plan((p) => [set(instance(Todo, p.todoId), "text", p.text)]);
51
43
 
52
- // The caller decides open↔done and rides it IN the payload (a plan is pure — no clock,
44
+ // The caller decides done/not-done and rides it IN the payload (a plan is pure — no clock,
53
45
  // no random). Concurrent toggles are Lww: the later HLC wins, and both peers converge.
54
46
  export const toggleTodo = directive("toggleTodo")
55
47
  .mutates(Todo)
56
- .payload(z.object({ todoId: z.string(), done: z.enum(DONE) }))
48
+ .payload(z.object({ todoId: z.string(), done: z.boolean() }))
57
49
  .plan((p) => [set(instance(Todo, p.todoId), "done", p.done)]);
58
50
 
59
51
  // addToSet is the ONLY additive write to an AddWins set (set() would overwrite).
@@ -77,9 +69,9 @@ export const shareList = directive("shareList")
77
69
  // ── what people read (auto-discovered by shape; routed to every peer) ───────────
78
70
  export const todosByList = query("todosByList").key("listId").returns(Todo);
79
71
 
80
- // An O(1) maintained tally: how many todos are still open, per list.
72
+ // An O(1) maintained tally: how many todos are still open (done = false), per list.
81
73
  export const openTodosByList = count("openTodosByList")
82
- .of(Todo).where((p) => p.field("done").eq("open")).by("listId");
74
+ .of(Todo).where((p) => p.field("done").eq(false)).by("listId");
83
75
 
84
76
  // The raw sharing tuples for a list — the audit surface (re-exported so it routes here).
85
77
  export { relationTuplesByObject };
@@ -1,7 +1,8 @@
1
1
  // The githolon-compile config: one package, one domain, one module file.
2
2
  // Read-side declarations (the query + the count) are auto-discovered from the
3
3
  // module's exports by shape — nothing to wire here. The framework RelationTuple
4
- // aggregate + its relationTuplesByObject query are pulled in by todo.ts's re-exports.
4
+ // aggregate is auto-injected by shareList's `.ensures(RelationTuple)`; todo.ts only
5
+ // re-exports the relationTuplesByObject query (the read side).
5
6
  // Building a Flutter app too? Add `dart: true` for the typed Dart frontend
6
7
  // (build/dart/) alongside the TS client.
7
8
  export default {
@@ -73,7 +73,7 @@ ok("typed offline writes — createList + 2 addTodo, under the pulled law");
73
73
  const seeded = await app.todosByList({ listId });
74
74
  if (seeded.length !== 2) fail(`local query: expected 2 todos, got ${seeded.length}`);
75
75
  const t1 = seeded.find((row) => row.data.text === "Draft the deck")!.id;
76
- await app.toggleTodo({ todoId: t1, done: "done" }); // Lww enum — open ↔ done
76
+ await app.toggleTodo({ todoId: t1, done: true }); // Lww boolean (t.bool)
77
77
  await app.tagTodo({ todoId: t1, tags: ["urgent", "q3"] }); // AddWins set
78
78
  ok(`read back a minted Todo id (${t1.slice(0, 16)}…) → toggled done + tagged`);
79
79