MIRROR: javascript for 馃悳's, a tiny runtime with big ambitions
1class ReactPromise {
2 constructor(status, value, reason) {
3 this.status = status;
4 this.value = value;
5 this.reason = reason;
6 }
7}
8
9function createPendingChunk(response) {
10 return new ReactPromise("pending", null, null);
11}
12
13function createResolvedIteratorResultChunk(response, value, done) {
14 return new ReactPromise(
15 "resolved_model",
16 (done ? "{\"done\":true,\"value\":" : "{\"done\":false,\"value\":") + value + "}",
17 response
18 );
19}
20
21function resolveModelChunk(response, chunk, value) {
22 if ("pending" !== chunk.status) {
23 return chunk.reason.enqueueModel(value);
24 }
25
26 chunk.status = "resolved_model";
27 chunk.value = value;
28 chunk.reason = response;
29}
30
31function resolveIteratorResultChunk(response, chunk, value, done) {
32 resolveModelChunk(
33 response,
34 chunk,
35 (done ? "{\"done\":true,\"value\":" : "{\"done\":false,\"value\":") + value + "}"
36 );
37}
38
39function startAsyncIterable(response) {
40 const buffer = [];
41 let closed = false;
42 let nextWriteIndex = 0;
43
44 const iterable = {};
45 iterable[Symbol.asyncIterator] = function () {
46 let nextReadIndex = 0;
47 return {
48 next(arg) {
49 if (arg !== undefined) throw new Error("bad arg");
50 if (nextReadIndex === buffer.length) {
51 if (closed) {
52 return new ReactPromise("fulfilled", { done: true, value: undefined }, null);
53 }
54 buffer[nextReadIndex] = createPendingChunk(response);
55 }
56 return buffer[nextReadIndex++];
57 }
58 };
59 };
60
61 return {
62 buffer,
63 iterator: iterable[Symbol.asyncIterator](),
64 enqueueModel(value) {
65 if (nextWriteIndex === buffer.length) {
66 buffer[nextWriteIndex] = createResolvedIteratorResultChunk(response, value, false);
67 } else {
68 resolveIteratorResultChunk(response, buffer[nextWriteIndex], value, false);
69 }
70 nextWriteIndex++;
71 }
72 };
73}
74
75const response = {
76 seen: [],
77 enqueueModel(value) {
78 this.seen.push(value);
79 }
80};
81
82const state = startAsyncIterable(response);
83
84console.log(`len0:${state.buffer.length}`);
85const first = state.iterator.next();
86console.log(`len1:${state.buffer.length}`);
87console.log(`first.status:${first.status}`);
88
89state.enqueueModel("1");
90console.log(`len2:${state.buffer.length}`);
91console.log(`slot0.status:${state.buffer[0].status}`);
92console.log(`slot0.reasonType:${typeof state.buffer[0].reason}`);
93
94state.enqueueModel("2");
95console.log(`len3:${state.buffer.length}`);
96console.log(`seen:${response.seen.join(",")}`);