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.
- package/dist/account.test.js +1 -1
- package/dist/account.test.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/streamUtils.d.ts +8 -0
- package/dist/streamUtils.js +95 -0
- package/dist/streamUtils.js.map +1 -0
- package/dist/sync.js +1 -1
- package/dist/sync.js.map +1 -1
- package/dist/sync.test.js +2 -1
- package/dist/sync.test.js.map +1 -1
- package/dist/testUtils.d.ts +0 -8
- package/dist/testUtils.js +0 -94
- package/dist/testUtils.js.map +1 -1
- package/package.json +3 -2
- package/src/account.test.ts +1 -1
- package/src/index.ts +2 -0
- package/src/streamUtils.ts +130 -0
- package/src/sync.test.ts +4 -2
- package/src/sync.ts +1 -1
- package/src/testUtils.ts +0 -130
- package/yarn-error.log +0 -2864
|
@@ -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
|
-
}
|