cojson 0.0.13 → 0.0.15

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.
@@ -0,0 +1,130 @@
1
+ import { ReadableStream, TransformStream, WritableStream } from "isomorphic-streams";
2
+ import { Peer, PeerID, SyncMessage } from "./sync.js";
3
+
4
+
5
+ export function connectedPeers(
6
+ peer1id: PeerID,
7
+ peer2id: PeerID,
8
+ {
9
+ trace = false, peer1role = "peer", peer2role = "peer",
10
+ }: {
11
+ trace?: boolean;
12
+ peer1role?: Peer["role"];
13
+ peer2role?: Peer["role"];
14
+ } = {}
15
+ ): [Peer, Peer] {
16
+ const [inRx1, inTx1] = newStreamPair<SyncMessage>();
17
+ const [outRx1, outTx1] = newStreamPair<SyncMessage>();
18
+
19
+ const [inRx2, inTx2] = newStreamPair<SyncMessage>();
20
+ const [outRx2, outTx2] = newStreamPair<SyncMessage>();
21
+
22
+ void outRx2
23
+ .pipeThrough(
24
+ new TransformStream({
25
+ transform(
26
+ chunk: SyncMessage,
27
+ controller: { enqueue: (msg: SyncMessage) => void; }
28
+ ) {
29
+ trace && console.log(`${peer2id} -> ${peer1id}`, JSON.stringify(chunk, null, 2));
30
+ controller.enqueue(chunk);
31
+ },
32
+ })
33
+ )
34
+ .pipeTo(inTx1);
35
+
36
+ void outRx1
37
+ .pipeThrough(
38
+ new TransformStream({
39
+ transform(
40
+ chunk: SyncMessage,
41
+ controller: { enqueue: (msg: SyncMessage) => void; }
42
+ ) {
43
+ trace && console.log(`${peer1id} -> ${peer2id}`, JSON.stringify(chunk, null, 2));
44
+ controller.enqueue(chunk);
45
+ },
46
+ })
47
+ )
48
+ .pipeTo(inTx2);
49
+
50
+ const peer2AsPeer: Peer = {
51
+ id: peer2id,
52
+ incoming: inRx1,
53
+ outgoing: outTx1,
54
+ role: peer2role,
55
+ };
56
+
57
+ const peer1AsPeer: Peer = {
58
+ id: peer1id,
59
+ incoming: inRx2,
60
+ outgoing: outTx2,
61
+ role: peer1role,
62
+ };
63
+
64
+ return [peer1AsPeer, peer2AsPeer];
65
+ }
66
+
67
+ export function newStreamPair<T>(): [ReadableStream<T>, WritableStream<T>] {
68
+ const queue: T[] = [];
69
+ let resolveNextItemReady: () => void = () => { };
70
+ let nextItemReady: Promise<void> = new Promise((resolve) => {
71
+ resolveNextItemReady = resolve;
72
+ });
73
+
74
+ let writerClosed = false;
75
+ let readerClosed = false;
76
+
77
+ const readable = new ReadableStream<T>({
78
+ async pull(controller) {
79
+ let retriesLeft = 3;
80
+ while (retriesLeft > 0) {
81
+ if (writerClosed) {
82
+ controller.close();
83
+ return;
84
+ }
85
+ retriesLeft--;
86
+ if (queue.length > 0) {
87
+ controller.enqueue(queue.shift()!);
88
+ if (queue.length === 0) {
89
+ nextItemReady = new Promise((resolve) => {
90
+ resolveNextItemReady = resolve;
91
+ });
92
+ }
93
+ return;
94
+ } else {
95
+ await nextItemReady;
96
+ }
97
+ }
98
+ throw new Error(
99
+ "Should only use one retry to get next item in queue."
100
+ );
101
+ },
102
+
103
+ cancel(reason) {
104
+ console.log("Manually closing reader");
105
+ readerClosed = true;
106
+ },
107
+ });
108
+
109
+ const writable = new WritableStream<T>({
110
+ write(chunk, controller) {
111
+ if (readerClosed) {
112
+ console.log("Reader closed, not writing chunk", chunk);
113
+ throw new Error("Reader closed, not writing chunk");
114
+ }
115
+ queue.push(chunk);
116
+ if (queue.length === 1) {
117
+ // make sure that await write resolves before corresponding read
118
+ setTimeout(() => resolveNextItemReady());
119
+ }
120
+ },
121
+ abort(reason) {
122
+ console.log("Manually closing writer");
123
+ writerClosed = true;
124
+ resolveNextItemReady();
125
+ return Promise.resolve();
126
+ },
127
+ });
128
+
129
+ return [readable, writable];
130
+ }
package/src/sync.test.ts CHANGED
@@ -10,11 +10,13 @@ import {
10
10
  TransformStream,
11
11
  } from "isomorphic-streams";
12
12
  import {
13
- connectedPeers,
14
- newStreamPair,
15
13
  randomAnonymousAccountAndSessionID,
16
14
  shouldNotResolve,
17
15
  } from "./testUtils.js";
16
+ import {
17
+ connectedPeers,
18
+ newStreamPair
19
+ } from "./streamUtils.js";
18
20
  import { AccountID } from "./account.js";
19
21
 
20
22
  test("Node replies with initial tx and header to empty subscribe", async () => {
package/src/sync.ts CHANGED
@@ -285,7 +285,7 @@ export class SyncManager {
285
285
 
286
286
  trySendToPeer(peer: PeerState, msg: SyncMessage) {
287
287
  return peer.outgoing.write(msg).catch((e) => {
288
- console.error("Error writing to peer, disconnecting", e);
288
+ console.error(new Error("Error writing to peer, disconnecting", {cause: e}));
289
289
  delete this.peers[peer.id];
290
290
  });
291
291
  }
package/src/testUtils.ts CHANGED
@@ -4,8 +4,6 @@ import { LocalNode } from "./node.js";
4
4
  import { expectTeamContent } from "./permissions.js";
5
5
  import { AnonymousControlledAccount } from "./account.js";
6
6
  import { SessionID } from "./ids.js";
7
- import { ReadableStream, TransformStream, WritableStream } from "isomorphic-streams";
8
- import { Peer, PeerID, SyncMessage } from "./sync.js";
9
7
 
10
8
  export function randomAnonymousAccountAndSessionID(): [AnonymousControlledAccount, SessionID] {
11
9
  const agentSecret = newRandomAgentSecret();
@@ -80,71 +78,6 @@ export function teamWithTwoAdminsHighLevel() {
80
78
  return { admin, node, team, otherAdmin };
81
79
  }
82
80
 
83
- export function newStreamPair<T>(): [ReadableStream<T>, WritableStream<T>] {
84
- const queue: T[] = [];
85
- let resolveNextItemReady: () => void = () => {};
86
- let nextItemReady: Promise<void> = new Promise((resolve) => {
87
- resolveNextItemReady = resolve;
88
- });
89
-
90
- let writerClosed = false;
91
- let readerClosed = false;
92
-
93
- const readable = new ReadableStream<T>({
94
- async pull(controller) {
95
- let retriesLeft = 3;
96
- while (retriesLeft > 0) {
97
- if (writerClosed) {
98
- controller.close();
99
- return;
100
- }
101
- retriesLeft--;
102
- if (queue.length > 0) {
103
- controller.enqueue(queue.shift()!);
104
- if (queue.length === 0) {
105
- nextItemReady = new Promise((resolve) => {
106
- resolveNextItemReady = resolve;
107
- });
108
- }
109
- return;
110
- } else {
111
- await nextItemReady;
112
- }
113
- }
114
- throw new Error(
115
- "Should only use one retry to get next item in queue."
116
- );
117
- },
118
-
119
- cancel(reason) {
120
- console.log("Manually closing reader");
121
- readerClosed = true;
122
- },
123
- });
124
-
125
- const writable = new WritableStream<T>({
126
- write(chunk, controller) {
127
- if (readerClosed) {
128
- console.log("Reader closed, not writing chunk", chunk);
129
- throw new Error("Reader closed, not writing chunk");
130
- }
131
- queue.push(chunk);
132
- if (queue.length === 1) {
133
- // make sure that await write resolves before corresponding read
134
- process.nextTick(() => resolveNextItemReady());
135
- }
136
- },
137
- abort(reason) {
138
- console.log("Manually closing writer");
139
- writerClosed = true;
140
- resolveNextItemReady();
141
- return Promise.resolve();
142
- },
143
- });
144
-
145
- return [readable, writable];
146
- }
147
-
148
81
  export function shouldNotResolve<T>(
149
82
  promise: Promise<T>,
150
83
  ops: { timeout: number }
@@ -164,66 +97,3 @@ export function shouldNotResolve<T>(
164
97
  });
165
98
  }
166
99
 
167
- export function connectedPeers(
168
- peer1id: PeerID,
169
- peer2id: PeerID,
170
- {
171
- trace = false,
172
- peer1role = "peer",
173
- peer2role = "peer",
174
- }: {
175
- trace?: boolean;
176
- peer1role?: Peer["role"];
177
- peer2role?: Peer["role"];
178
- } = {}
179
- ): [Peer, Peer] {
180
- const [inRx1, inTx1] = newStreamPair<SyncMessage>();
181
- const [outRx1, outTx1] = newStreamPair<SyncMessage>();
182
-
183
- const [inRx2, inTx2] = newStreamPair<SyncMessage>();
184
- const [outRx2, outTx2] = newStreamPair<SyncMessage>();
185
-
186
- void outRx2
187
- .pipeThrough(
188
- new TransformStream({
189
- transform(
190
- chunk: SyncMessage,
191
- controller: { enqueue: (msg: SyncMessage) => void }
192
- ) {
193
- trace && console.log(`${peer2id} -> ${peer1id}`, JSON.stringify(chunk, null, 2));
194
- controller.enqueue(chunk);
195
- },
196
- })
197
- )
198
- .pipeTo(inTx1);
199
-
200
- void outRx1
201
- .pipeThrough(
202
- new TransformStream({
203
- transform(
204
- chunk: SyncMessage,
205
- controller: { enqueue: (msg: SyncMessage) => void }
206
- ) {
207
- trace && console.log(`${peer1id} -> ${peer2id}`, JSON.stringify(chunk, null, 2));
208
- controller.enqueue(chunk);
209
- },
210
- })
211
- )
212
- .pipeTo(inTx2);
213
-
214
- const peer2AsPeer: Peer = {
215
- id: peer2id,
216
- incoming: inRx1,
217
- outgoing: outTx1,
218
- role: peer2role,
219
- };
220
-
221
- const peer1AsPeer: Peer = {
222
- id: peer1id,
223
- incoming: inRx2,
224
- outgoing: outTx2,
225
- role: peer1role,
226
- };
227
-
228
- return [peer1AsPeer, peer2AsPeer];
229
- }