annotate src/SourceGraph.ts @ 139:cf642d395be4

new simpler Patch class; fancier 'hide' view config support
author drewp@bigasterisk.com
date Mon, 08 May 2023 13:05:20 -0700
parents a8939c717015
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
128
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
1 import { JsonLdParser } from "jsonld-streaming-parser";
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
2 import { Parser, Store } from "n3";
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
3 import { SubEvent } from "sub-events";
139
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
4 import { Patch, PatchDirection } from "./Patch";
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
5
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
6 type JsonLdData = Object;
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
7
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
8 interface CombinedPatchBody {
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
9 adds?: JsonLdData;
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
10 deletes?: JsonLdData;
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
11 }
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
12 interface CombinedPatchEvent {
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
13 patch: CombinedPatchBody;
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
14 }
128
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
15
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
16 // Possibly-changing graph for one source. Maintains its own dataset.
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
17 // Read-only.
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
18 //
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
19 // Rename to RemoteGraph? RemoteStore? SyncedStore? PatchableGraph?
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
20 export class SourceGraph {
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
21 store: Store; // const; do not rebuild
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
22 isCurrent: boolean = false;
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
23 sourceGraphChanged: SubEvent<Patch> = new SubEvent();
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
24 constructor(public url: string /* immutable */) {
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
25 this.store = new Store();
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
26 }
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
27
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
28 dispose() {}
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
29
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
30 // Call this first, after you've subscribed to `sourceGraphChanged`. This call may
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
31 // synchronously fire change events.
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
32 //
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
33 async reloadRdf() {
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
34 const resp = await fetch(this.url);
139
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
35 this.clearStore();
128
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
36 const ctype = resp.headers.get("content-type");
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
37 if (ctype?.startsWith("text/event-stream")) {
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
38 await this.reloadEventStream();
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
39 } else {
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
40 await this.reloadSimpleFile(resp);
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
41 }
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
42 }
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
43
139
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
44 private clearStore() {
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
45 this.store.removeMatches(null, null, null, null);
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
46 }
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
47
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
48 async makePatchFromParsed(
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
49 dir: PatchDirection,
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
50 jsonLdObj: Object | undefined
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
51 ): Promise<Patch> {
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
52 const p = new Patch(dir);
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
53 if (jsonLdObj === undefined) {
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
54 return p;
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
55 }
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
56 const parser = new JsonLdParser();
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
57
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
58 parser.write(JSON.stringify(jsonLdObj));
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
59 parser.end();
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
60
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
61 await p.streamImport(parser);
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
62 return p;
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
63 }
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
64
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
65 private applyPatch(p: Patch) {
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
66 if (p.isEmpty()){
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
67 return;
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
68 }
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
69 p.applyToStore(this.store);
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
70 if (this.sourceGraphChanged.getStat().unnamed == 0) {
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
71 console.warn("no listeners to this sourceGraphChanged event");
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
72 }
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
73 this.sourceGraphChanged.emit(p);
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
74 }
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
75
128
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
76 private async reloadEventStream(): Promise<void> {
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
77 return new Promise((res, rej) => {
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
78 const ev = new EventSource(this.url);
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
79
139
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
80 // old-style fullGraph. I now think it would be better to send plain
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
81 // adds and for this SourceGraph to emptyGraph when there's a new connection.
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
82 ev.addEventListener("fullGraph", async (ev) => {
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
83 this.clearStore();
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
84 const p = new Patch(PatchDirection.ADD);
128
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
85 const parser = new JsonLdParser();
139
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
86 parser.write(ev.data);
128
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
87 parser.end();
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
88
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
89 await p.streamImport(parser);
139
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
90 p.applyToStore(this.store);
128
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
91 this.isCurrent = true;
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
92 this.sourceGraphChanged.emit(p);
139
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
93 res();
128
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
94 });
139
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
95
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
96 // this is for old-style dels-then-adds patches
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
97 ev.addEventListener("patch", async (ev) => {
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
98 // this is reentrant- patches might be able to get applied out of order!
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
99
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
100 const patchMsg: CombinedPatchEvent = JSON.parse((ev as any).data);
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
101
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
102 const p0 = await this.makePatchFromParsed(
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
103 PatchDirection.DEL,
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
104 patchMsg.patch.deletes
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
105 );
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
106 const p1 = await this.makePatchFromParsed(
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
107 PatchDirection.ADD,
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
108 patchMsg.patch.adds
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
109 );
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
110
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
111 this.applyPatch(p0);
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
112 this.applyPatch(p1);
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
113
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
114 this.isCurrent = true;
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
115 });
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
116 // here, add listeners for new-style add/del patches
128
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
117 });
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
118 }
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
119
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
120 private async reloadSimpleFile(resp: Response) {
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
121 const bodyText = await resp.text();
139
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
122 const p = new Patch(PatchDirection.ADD);
128
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
123 const parser = new Parser({ format: "application/trig" });
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
124 await new Promise<void>((res, rej) => {
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
125 parser.parse(bodyText, (error, quad, prefixes) => {
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
126 if (error) {
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
127 console.log("parse ~ error:", error);
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
128 rej(error);
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
129 return;
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
130 }
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
131 if (quad) {
139
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
132 p.quads.push(quad);
128
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
133 } else {
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
134 res();
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
135 }
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
136 });
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
137 });
139
cf642d395be4 new simpler Patch class; fancier 'hide' view config support
drewp@bigasterisk.com
parents: 137
diff changeset
138 this.applyPatch(p);
128
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
139 this.isCurrent = true;
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
140 }
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
141
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
142 quadCount(): number {
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
143 return this.store.countQuads(null, null, null, null);
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
144 }
5a1a79f54779 big rewrite
drewp@bigasterisk.com
parents:
diff changeset
145 }