chem-rx 0.0.23 → 0.2.0
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/CHANGELOG.md +26 -0
- package/README.md +145 -33
- package/dist/Atom.d.ts +88 -48
- package/dist/Atom.d.ts.map +1 -1
- package/dist/Signal.d.ts +4 -5
- package/dist/Signal.d.ts.map +1 -1
- package/dist/index.cjs.js +423 -295
- package/dist/index.d.ts +1 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.iife.js +425 -294
- package/dist/index.mjs +423 -0
- package/dist/react.cjs.js +50 -0
- package/{src/index.ts → dist/react.d.ts} +1 -3
- package/dist/react.d.ts.map +1 -0
- package/dist/react.mjs +40 -0
- package/dist/store.d.ts +30 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/useAtom.d.ts +2 -2
- package/dist/useAtom.d.ts.map +1 -1
- package/dist/useHydrateAtoms.d.ts.map +1 -1
- package/dist/useSelectAtom.d.ts.map +1 -1
- package/package.json +34 -16
- package/.size-snapshot.json +0 -26
- package/babel.config.js +0 -24
- package/dist/index.js +0 -301
- package/dist/types.d.ts +0 -32
- package/dist/types.d.ts.map +0 -1
- package/rollup.config.js +0 -92
- package/src/Atom.ts +0 -374
- package/src/Signal.ts +0 -38
- package/src/types.ts +0 -66
- package/src/useAtom.ts +0 -20
- package/src/useHydrateAtoms.ts +0 -16
- package/src/useSelectAtom.ts +0 -25
- package/src/useSignal.ts +0 -24
- package/tests/atom.test.ts +0 -625
- package/tests/sample.ts +0 -123
- package/tsconfig.json +0 -23
package/tests/atom.test.ts
DELETED
|
@@ -1,625 +0,0 @@
|
|
|
1
|
-
import { ArrayAtom, Atom, BaseAtom, ReadOnlyAtom } from "../src/Atom";
|
|
2
|
-
import { Signal } from "../src/Signal";
|
|
3
|
-
import { BehaviorSubject, map } from "rxjs";
|
|
4
|
-
|
|
5
|
-
test("Base Atom values test", () => {
|
|
6
|
-
const atom = Atom("aweofij");
|
|
7
|
-
expect(atom instanceof BaseAtom).toBe(true);
|
|
8
|
-
expect(atom.value()).toBe("aweofij");
|
|
9
|
-
|
|
10
|
-
atom.next("apro");
|
|
11
|
-
|
|
12
|
-
expect(atom.value()).toBe("apro");
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
test("Test readonly", () => {
|
|
16
|
-
const atom = Atom({ a: 10 }, true);
|
|
17
|
-
expect(atom instanceof ReadOnlyAtom).toBe(true);
|
|
18
|
-
expect(atom instanceof BaseAtom).toBe(false);
|
|
19
|
-
expect(atom.get("a")).toBe(10);
|
|
20
|
-
|
|
21
|
-
expect(atom).not.toHaveProperty("set");
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
test("Object Atom values test", () => {
|
|
25
|
-
const atom = Atom<{ [key: string]: string }>({
|
|
26
|
-
firstKey: "firstValue",
|
|
27
|
-
secondKey: "secondValue",
|
|
28
|
-
});
|
|
29
|
-
expect(atom instanceof BaseAtom).toBe(true);
|
|
30
|
-
expect(atom.value()["firstKey"]).toBe("firstValue");
|
|
31
|
-
|
|
32
|
-
expect(atom.value()["secondKey"]).toBe("secondValue");
|
|
33
|
-
atom.set("secondKey", "newSecondValue");
|
|
34
|
-
expect(atom.value()["secondKey"]).toBe("newSecondValue");
|
|
35
|
-
|
|
36
|
-
expect(atom.value()["thirdKey"]).toBeUndefined();
|
|
37
|
-
expect(atom.value()).not.toHaveProperty("thirdKey");
|
|
38
|
-
atom.set("thirdKey", "thirdValue");
|
|
39
|
-
expect(atom.value()["thirdKey"]).toBe("thirdValue");
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
test("Object Atom get function test", () => {
|
|
43
|
-
const atom = Atom<{ [key: string]: string }>({
|
|
44
|
-
firstKey: "firstValue",
|
|
45
|
-
secondKey: "secondValue",
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
expect(atom.get("firey")).toBe(undefined);
|
|
49
|
-
|
|
50
|
-
expect(atom instanceof BaseAtom).toBe(true);
|
|
51
|
-
expect(atom.get("firstKey")).toBe("firstValue");
|
|
52
|
-
|
|
53
|
-
expect(atom.get("secondKey")).toBe("secondValue");
|
|
54
|
-
atom.set("secondKey", "newSecondValue");
|
|
55
|
-
expect(atom.get("secondKey")).toBe("newSecondValue");
|
|
56
|
-
|
|
57
|
-
expect(atom.get("thirdKey")).toBeUndefined();
|
|
58
|
-
expect(atom.value()).not.toHaveProperty("thirdKey");
|
|
59
|
-
atom.set("thirdKey", "thirdValue");
|
|
60
|
-
expect(atom.get("thirdKey")).toBe("thirdValue");
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
test("Object Enum Atom test", () => {
|
|
64
|
-
enum testEnum {
|
|
65
|
-
first,
|
|
66
|
-
second,
|
|
67
|
-
}
|
|
68
|
-
const atom = Atom({
|
|
69
|
-
[testEnum.first]: "firstValue",
|
|
70
|
-
[testEnum.second]: "secondValue",
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
// this should always be defined as a string
|
|
74
|
-
const kkk = atom.get(testEnum.first);
|
|
75
|
-
kkk.toString();
|
|
76
|
-
|
|
77
|
-
expect(atom instanceof BaseAtom).toBe(true);
|
|
78
|
-
expect(atom.get(testEnum.first)).toBe("firstValue");
|
|
79
|
-
|
|
80
|
-
expect(atom.get(testEnum.second)).toBe("secondValue");
|
|
81
|
-
atom.set(testEnum.second, "newSecondValue");
|
|
82
|
-
expect(atom.get(testEnum.second)).toBe("newSecondValue");
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
test("Optional keys Object Atom test", () => {
|
|
86
|
-
enum testEnum {
|
|
87
|
-
first,
|
|
88
|
-
second,
|
|
89
|
-
}
|
|
90
|
-
const atom = Atom<{
|
|
91
|
-
[testEnum.first]?: string;
|
|
92
|
-
[testEnum.second]?: string;
|
|
93
|
-
}>({
|
|
94
|
-
[testEnum.first]: "firstValue",
|
|
95
|
-
[testEnum.second]: "secondValue",
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
const kkk = atom.get(testEnum.first);
|
|
99
|
-
// @ts-expect-error this should be possibly undefined
|
|
100
|
-
kkk.toString();
|
|
101
|
-
|
|
102
|
-
expect(atom instanceof BaseAtom).toBe(true);
|
|
103
|
-
expect(atom.get(testEnum.first)).toBe("firstValue");
|
|
104
|
-
|
|
105
|
-
expect(atom.get(testEnum.second)).toBe("secondValue");
|
|
106
|
-
atom.set(testEnum.second, "newSecondValue");
|
|
107
|
-
expect(atom.get(testEnum.second)).toBe("newSecondValue");
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
test("Uninitialized Object Enum Atom test", () => {
|
|
111
|
-
enum testEnum {
|
|
112
|
-
first,
|
|
113
|
-
second,
|
|
114
|
-
}
|
|
115
|
-
const seedValue = {
|
|
116
|
-
[testEnum.first]: "firstValue",
|
|
117
|
-
[testEnum.second]: "secondValue",
|
|
118
|
-
};
|
|
119
|
-
const atom = Atom<{
|
|
120
|
-
[testEnum.first]: string;
|
|
121
|
-
[testEnum.second]: string;
|
|
122
|
-
}>();
|
|
123
|
-
|
|
124
|
-
const kkk = atom.get(testEnum.first);
|
|
125
|
-
// this should be possibly undefined at this point,
|
|
126
|
-
// so there should lbe type safety here
|
|
127
|
-
expect(() => {
|
|
128
|
-
// @ts-expect-error this should throw a type error
|
|
129
|
-
// because it should be possibly undefined
|
|
130
|
-
kkk.toString();
|
|
131
|
-
}).toThrow();
|
|
132
|
-
|
|
133
|
-
// atom.push({
|
|
134
|
-
// [testEnum.first]: "firstValue",
|
|
135
|
-
// [testEnum.second]: "secondValue",
|
|
136
|
-
// });
|
|
137
|
-
expect(atom instanceof BaseAtom).toBe(true);
|
|
138
|
-
|
|
139
|
-
expect(atom.get(testEnum.first)).toBe(undefined);
|
|
140
|
-
expect(atom.get(testEnum.second)).toBe(undefined);
|
|
141
|
-
atom.next(seedValue);
|
|
142
|
-
expect(atom.get(testEnum.first)).toBe("firstValue");
|
|
143
|
-
|
|
144
|
-
expect(atom.get(testEnum.second)).toBe("secondValue");
|
|
145
|
-
atom.set(testEnum.second, "newSecondValue");
|
|
146
|
-
expect(atom.get(testEnum.second)).toBe("newSecondValue");
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
test("Array Atom values test", () => {
|
|
150
|
-
const atom = Atom<string[]>(["first"]);
|
|
151
|
-
|
|
152
|
-
expect(atom.get(10)).toBe(undefined);
|
|
153
|
-
|
|
154
|
-
// this is not allowed
|
|
155
|
-
// atom.push(1);
|
|
156
|
-
expect(atom instanceof ArrayAtom).toBe(true);
|
|
157
|
-
expect(atom.value().length).toBe(1);
|
|
158
|
-
expect(atom.value()[0]).toBe("first");
|
|
159
|
-
|
|
160
|
-
atom.push("second");
|
|
161
|
-
expect(atom.value().length).toBe(2);
|
|
162
|
-
expect(atom.value()[1]).toBe("second");
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
test("Array Atom get index test", () => {
|
|
166
|
-
const atom = Atom<string[]>(["first"]);
|
|
167
|
-
|
|
168
|
-
expect(atom instanceof ArrayAtom).toBe(true);
|
|
169
|
-
expect(atom.value().length).toBe(1);
|
|
170
|
-
expect(atom.get(0)).toBe("first");
|
|
171
|
-
|
|
172
|
-
atom.push("second");
|
|
173
|
-
expect(atom.value().length).toBe(2);
|
|
174
|
-
expect(atom.get(1)).toBe("second");
|
|
175
|
-
|
|
176
|
-
expect(atom.get(2)).toBe(undefined);
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
test("Test native pipe", () => {
|
|
180
|
-
const atom = Atom(3);
|
|
181
|
-
expect(atom instanceof BaseAtom).toBe(true);
|
|
182
|
-
expect(atom.value()).toBe(3);
|
|
183
|
-
|
|
184
|
-
const derivedAtom = atom.pipe(map((x) => x * x));
|
|
185
|
-
expect(derivedAtom instanceof ReadOnlyAtom).toBe(true);
|
|
186
|
-
expect(derivedAtom).not.toHaveProperty("set");
|
|
187
|
-
|
|
188
|
-
expect(derivedAtom.value()).toBe(9);
|
|
189
|
-
});
|
|
190
|
-
|
|
191
|
-
test("Test derive", () => {
|
|
192
|
-
const atom = Atom(3);
|
|
193
|
-
expect(atom instanceof BaseAtom).toBe(true);
|
|
194
|
-
expect(atom.value()).toBe(3);
|
|
195
|
-
|
|
196
|
-
const derivedAtom = atom.derive((x) => x * x);
|
|
197
|
-
expect(derivedAtom instanceof ReadOnlyAtom).toBe(true);
|
|
198
|
-
expect(derivedAtom).not.toHaveProperty("set");
|
|
199
|
-
|
|
200
|
-
expect(derivedAtom.value()).toBe(9);
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
test("Test derive update", () => {
|
|
204
|
-
const atom = Atom(3);
|
|
205
|
-
expect(atom instanceof BaseAtom).toBe(true);
|
|
206
|
-
expect(atom.value()).toBe(3);
|
|
207
|
-
|
|
208
|
-
const derivedAtom = atom.derive((x) => x * x);
|
|
209
|
-
expect(derivedAtom instanceof ReadOnlyAtom).toBe(true);
|
|
210
|
-
expect(derivedAtom).not.toHaveProperty("set");
|
|
211
|
-
|
|
212
|
-
expect(derivedAtom.value()).toBe(9);
|
|
213
|
-
|
|
214
|
-
atom.next(4);
|
|
215
|
-
expect(derivedAtom.value()).toBe(16);
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
test("Test combine", () => {
|
|
219
|
-
const normalizedData = Atom<{ [key: string]: { name: string } }>({
|
|
220
|
-
a: { name: "a" },
|
|
221
|
-
b: { name: "b" },
|
|
222
|
-
c: { name: "c" },
|
|
223
|
-
});
|
|
224
|
-
const ids = Atom<string[]>(["a", "b", "c"]);
|
|
225
|
-
const combined = Atom.combine(normalizedData, ids).derive(([normed, ids]) => {
|
|
226
|
-
return ids.map((id) => normed[id]);
|
|
227
|
-
});
|
|
228
|
-
expect(combined).not.toHaveProperty("set");
|
|
229
|
-
|
|
230
|
-
expect(combined instanceof ReadOnlyAtom).toBe(true);
|
|
231
|
-
|
|
232
|
-
expect(combined instanceof ReadOnlyAtom).toBe(true);
|
|
233
|
-
expect(combined).not.toHaveProperty("set");
|
|
234
|
-
const combinedValue = combined.value();
|
|
235
|
-
expect(combinedValue.length).toBe(3);
|
|
236
|
-
expect(combinedValue[0].name).toBe("a");
|
|
237
|
-
expect(combinedValue[1].name).toBe("b");
|
|
238
|
-
expect(combinedValue[2].name).toBe("c");
|
|
239
|
-
});
|
|
240
|
-
|
|
241
|
-
test("Test combine example", () => {
|
|
242
|
-
const pets$ = Atom<{ [name: string]: { type: "dog" | "cat"; age: number } }>({
|
|
243
|
-
spot: { type: "dog", age: 5 },
|
|
244
|
-
fido: { type: "dog", age: 3 },
|
|
245
|
-
tabby: { type: "cat", age: 12 },
|
|
246
|
-
});
|
|
247
|
-
|
|
248
|
-
const people$ = Atom<{ [name: string]: { pets: string[] } }>({
|
|
249
|
-
fred: { pets: [] },
|
|
250
|
-
mary: { pets: ["spot", "fido"] },
|
|
251
|
-
cam: { pets: ["tabby"] },
|
|
252
|
-
});
|
|
253
|
-
|
|
254
|
-
const mary$ = Atom.combine(pets$, people$.select("mary")).derive(
|
|
255
|
-
([pets, mary]) => {
|
|
256
|
-
return {
|
|
257
|
-
...mary,
|
|
258
|
-
pets: mary.pets.map((petName) => pets[petName]),
|
|
259
|
-
};
|
|
260
|
-
}
|
|
261
|
-
);
|
|
262
|
-
{
|
|
263
|
-
mary: {
|
|
264
|
-
pets: [
|
|
265
|
-
{
|
|
266
|
-
name: "spot",
|
|
267
|
-
type: "dog",
|
|
268
|
-
age: 5,
|
|
269
|
-
},
|
|
270
|
-
];
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
const a: number[] = [1, 3, 4, 5];
|
|
275
|
-
const b = a[10];
|
|
276
|
-
|
|
277
|
-
const pets = mary$.select("pets").get(0);
|
|
278
|
-
expect(mary$.select("pets").value().length).toBe(2);
|
|
279
|
-
expect(mary$.select("pets").get(0)).toHaveProperty("type");
|
|
280
|
-
expect(mary$.select("pets").get(0)).toHaveProperty("age");
|
|
281
|
-
expect(mary$.select("pets").get(0).type).toBe("dog");
|
|
282
|
-
expect(mary$.select("pets").get(0).age).toBe(5);
|
|
283
|
-
expect(mary$.select("pets").get(1)).toHaveProperty("type");
|
|
284
|
-
expect(mary$.select("pets").get(1)).toHaveProperty("age");
|
|
285
|
-
expect(mary$.select("pets").get(1).type).toBe("dog");
|
|
286
|
-
expect(mary$.select("pets").get(1).age).toBe(3);
|
|
287
|
-
});
|
|
288
|
-
|
|
289
|
-
test("Test select (simple)", () => {
|
|
290
|
-
enum TEST_ENUM {
|
|
291
|
-
a = "weoifj",
|
|
292
|
-
b = "oh",
|
|
293
|
-
c = "ohoij",
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
// test types
|
|
297
|
-
const enumTest = Atom(TEST_ENUM.a);
|
|
298
|
-
|
|
299
|
-
const arrayTest = Atom([1, 2, 34]);
|
|
300
|
-
const arrayTest2 = Atom([{ a: "jwoi" }, 2, 34]);
|
|
301
|
-
|
|
302
|
-
const arrayAtom = Atom<{ [key: string]: number[] }>({
|
|
303
|
-
a: [0, 1, 2],
|
|
304
|
-
b: [1, 3, 4],
|
|
305
|
-
c: [5, 3, 4],
|
|
306
|
-
});
|
|
307
|
-
|
|
308
|
-
const primitiveNum = new BehaviorSubject(4);
|
|
309
|
-
const primitiveNumAtom = Atom<number>(primitiveNum);
|
|
310
|
-
|
|
311
|
-
const primitiveStr = new BehaviorSubject("a");
|
|
312
|
-
const primitiveStringAtom = Atom<string>(primitiveStr);
|
|
313
|
-
|
|
314
|
-
const arrayObs = new BehaviorSubject(["a"]);
|
|
315
|
-
const arrayObsAtom = Atom<string[]>(arrayObs);
|
|
316
|
-
|
|
317
|
-
const objObs = new BehaviorSubject({ a: 1 });
|
|
318
|
-
const objObsAtom2 = Atom(objObs);
|
|
319
|
-
const objObsAtom1 = Atom<{ [id: string]: number }>(objObs);
|
|
320
|
-
|
|
321
|
-
const stringData = Atom<{
|
|
322
|
-
[key: string]: { [key: string]: string };
|
|
323
|
-
}>({
|
|
324
|
-
a: { a: "a" },
|
|
325
|
-
b: { b: "b" },
|
|
326
|
-
c: { c: "c" },
|
|
327
|
-
});
|
|
328
|
-
|
|
329
|
-
const selectedString: BaseAtom<{ [key: string]: string }> =
|
|
330
|
-
stringData.select("b");
|
|
331
|
-
|
|
332
|
-
const normalizedOptionalStringData = Atom<{
|
|
333
|
-
[key: string]: { [key in "a" | "b" | "c"]?: string };
|
|
334
|
-
}>({
|
|
335
|
-
a: { a: "a" },
|
|
336
|
-
b: { b: "b" },
|
|
337
|
-
c: { c: "c" },
|
|
338
|
-
});
|
|
339
|
-
|
|
340
|
-
const selectedOptionalString = normalizedOptionalStringData.select("b");
|
|
341
|
-
|
|
342
|
-
const normalizedEnumData = Atom<{
|
|
343
|
-
[key: string]: { [key in TEST_ENUM]?: string };
|
|
344
|
-
}>({
|
|
345
|
-
a: { [TEST_ENUM.a]: "a" },
|
|
346
|
-
b: { [TEST_ENUM.b]: "b" },
|
|
347
|
-
c: { [TEST_ENUM.c]: "c" },
|
|
348
|
-
});
|
|
349
|
-
const selected = normalizedEnumData.select("b");
|
|
350
|
-
const selected2 = normalizedEnumData.select("a");
|
|
351
|
-
const selectedArray = arrayAtom.select("b");
|
|
352
|
-
|
|
353
|
-
// THIS IS HTE LAST ONE THT STILL OES NOTWOK
|
|
354
|
-
const selectedArr = arrayAtom.select("a");
|
|
355
|
-
|
|
356
|
-
const sel3 = objObsAtom2.select("a");
|
|
357
|
-
|
|
358
|
-
expect(selected instanceof BaseAtom).toBe(true);
|
|
359
|
-
|
|
360
|
-
expect(selected instanceof BaseAtom).toBe(true);
|
|
361
|
-
|
|
362
|
-
// const combined = Atom.combine(normalizedData, ids).derive(([normed, ids]) => {
|
|
363
|
-
// return ids.map((id) => normed[id]);
|
|
364
|
-
// });
|
|
365
|
-
//
|
|
366
|
-
// expect(combined).not.toHaveProperty("push");
|
|
367
|
-
//
|
|
368
|
-
// expect(combined instanceof ReadOnlyAtom).toBe(true);
|
|
369
|
-
//
|
|
370
|
-
// expect(combined instanceof ReadOnlyAtom).toBe(true);
|
|
371
|
-
// expect(combined).not.toHaveProperty("push");
|
|
372
|
-
// const combinedValue = combined.value();
|
|
373
|
-
// expect(combinedValue.length).toBe(3);
|
|
374
|
-
// expect(combinedValue[0].name).toBe("a");
|
|
375
|
-
// expect(combinedValue[1].name).toBe("b");
|
|
376
|
-
// expect(combinedValue[2].name).toBe("c");
|
|
377
|
-
});
|
|
378
|
-
|
|
379
|
-
test("Test select (nested objects)", () => {
|
|
380
|
-
const nestedData = Atom<{
|
|
381
|
-
[key: string]: {
|
|
382
|
-
nickname: string;
|
|
383
|
-
education: {
|
|
384
|
-
school: string;
|
|
385
|
-
graduation: number;
|
|
386
|
-
};
|
|
387
|
-
};
|
|
388
|
-
}>({
|
|
389
|
-
stacy: {
|
|
390
|
-
nickname: "stace",
|
|
391
|
-
education: {
|
|
392
|
-
school: "Penn",
|
|
393
|
-
graduation: 2014,
|
|
394
|
-
},
|
|
395
|
-
},
|
|
396
|
-
annie: {
|
|
397
|
-
nickname: "ann",
|
|
398
|
-
education: {
|
|
399
|
-
school: "Brown",
|
|
400
|
-
graduation: 2015,
|
|
401
|
-
},
|
|
402
|
-
},
|
|
403
|
-
prabhu: {
|
|
404
|
-
nickname: "prab",
|
|
405
|
-
education: {
|
|
406
|
-
school: "MIT",
|
|
407
|
-
graduation: 2016,
|
|
408
|
-
},
|
|
409
|
-
},
|
|
410
|
-
});
|
|
411
|
-
const stacy = nestedData.select("stacy");
|
|
412
|
-
const stacySchool = nestedData.select("stacy").select("education");
|
|
413
|
-
|
|
414
|
-
const nickname = stacy.get("nickname");
|
|
415
|
-
const education = stacy.get("education");
|
|
416
|
-
expect(stacy.get("nickname")).toBe("stace");
|
|
417
|
-
expect(stacySchool.get("school")).toBe("Penn");
|
|
418
|
-
expect(stacySchool.get("graduation")).toBe(2014);
|
|
419
|
-
});
|
|
420
|
-
|
|
421
|
-
test("Test parent value when updating child objects ", () => {
|
|
422
|
-
const students = Atom<{
|
|
423
|
-
[key: string]: {
|
|
424
|
-
nickname: string;
|
|
425
|
-
education: {
|
|
426
|
-
school: string;
|
|
427
|
-
graduation: number;
|
|
428
|
-
};
|
|
429
|
-
};
|
|
430
|
-
}>({
|
|
431
|
-
stacy: {
|
|
432
|
-
nickname: "stace",
|
|
433
|
-
education: {
|
|
434
|
-
school: "Penn",
|
|
435
|
-
graduation: 2014,
|
|
436
|
-
},
|
|
437
|
-
},
|
|
438
|
-
annie: {
|
|
439
|
-
nickname: "ann",
|
|
440
|
-
education: {
|
|
441
|
-
school: "Brown",
|
|
442
|
-
graduation: 2015,
|
|
443
|
-
},
|
|
444
|
-
},
|
|
445
|
-
prabhu: {
|
|
446
|
-
nickname: "prab",
|
|
447
|
-
education: {
|
|
448
|
-
school: "MIT",
|
|
449
|
-
graduation: 2016,
|
|
450
|
-
},
|
|
451
|
-
},
|
|
452
|
-
});
|
|
453
|
-
const stacy = students.select("stacy");
|
|
454
|
-
const stacySchool = stacy.select("education");
|
|
455
|
-
|
|
456
|
-
expect(stacy.get("nickname")).toBe("stace");
|
|
457
|
-
expect(students.get("stacy").nickname).toBe("stace");
|
|
458
|
-
expect(stacySchool.get("graduation")).toBe(2014);
|
|
459
|
-
|
|
460
|
-
students.set("stacy", {
|
|
461
|
-
nickname: "spacey",
|
|
462
|
-
education: {
|
|
463
|
-
...students.get("stacy").education,
|
|
464
|
-
graduation: 2015,
|
|
465
|
-
},
|
|
466
|
-
});
|
|
467
|
-
|
|
468
|
-
expect(stacy.get("nickname")).toBe("spacey");
|
|
469
|
-
expect(students.get("stacy").nickname).toBe("spacey");
|
|
470
|
-
expect(stacySchool.get("graduation")).toBe(2015);
|
|
471
|
-
});
|
|
472
|
-
|
|
473
|
-
test("Test nullable object", () => {
|
|
474
|
-
const nestedData = Atom<{
|
|
475
|
-
[key: string]: {
|
|
476
|
-
nickname: string;
|
|
477
|
-
education: {
|
|
478
|
-
school: string;
|
|
479
|
-
graduation: number;
|
|
480
|
-
};
|
|
481
|
-
};
|
|
482
|
-
}>();
|
|
483
|
-
|
|
484
|
-
// TODO: This errors
|
|
485
|
-
const newVal = nestedData.select("stacy");
|
|
486
|
-
|
|
487
|
-
nestedData.next(undefined);
|
|
488
|
-
const stacy = nestedData.select("stacy");
|
|
489
|
-
const stacySchool = nestedData.select("stacy").select("education");
|
|
490
|
-
|
|
491
|
-
expect(stacy.get("nickname")).toBe(undefined);
|
|
492
|
-
expect(stacySchool.get("school")).toBe(undefined);
|
|
493
|
-
expect(stacySchool.value()).toBe(undefined);
|
|
494
|
-
nestedData.next(null);
|
|
495
|
-
expect(nestedData.value()).toBe(null);
|
|
496
|
-
});
|
|
497
|
-
|
|
498
|
-
test("Test select nullable object", () => {
|
|
499
|
-
const seedData = {
|
|
500
|
-
stacy: {
|
|
501
|
-
nickname: "stace",
|
|
502
|
-
education: {
|
|
503
|
-
school: "Penn",
|
|
504
|
-
graduation: 2014,
|
|
505
|
-
},
|
|
506
|
-
},
|
|
507
|
-
annie: {
|
|
508
|
-
nickname: "ann",
|
|
509
|
-
education: {
|
|
510
|
-
school: "Brown",
|
|
511
|
-
graduation: 2015,
|
|
512
|
-
},
|
|
513
|
-
},
|
|
514
|
-
prabhu: {
|
|
515
|
-
nickname: "prab",
|
|
516
|
-
education: {
|
|
517
|
-
school: "MIT",
|
|
518
|
-
graduation: 2016,
|
|
519
|
-
},
|
|
520
|
-
},
|
|
521
|
-
};
|
|
522
|
-
const nestedData = Atom<{
|
|
523
|
-
[key: string]: {
|
|
524
|
-
nickname: string;
|
|
525
|
-
education: {
|
|
526
|
-
school: string;
|
|
527
|
-
graduation: number;
|
|
528
|
-
};
|
|
529
|
-
};
|
|
530
|
-
}>();
|
|
531
|
-
|
|
532
|
-
// TODO: This errors
|
|
533
|
-
const newVal = nestedData.select("stacy");
|
|
534
|
-
|
|
535
|
-
nestedData.next(seedData);
|
|
536
|
-
const stacy = nestedData.select("stacy");
|
|
537
|
-
const stacySchool = nestedData.select("stacy").select("education");
|
|
538
|
-
|
|
539
|
-
expect(stacy.get("nickname")).toBe("stace");
|
|
540
|
-
expect(stacySchool.get("school")).toBe("Penn");
|
|
541
|
-
expect(stacySchool.get("graduation")).toBe(2014);
|
|
542
|
-
});
|
|
543
|
-
|
|
544
|
-
describe("SignalWithId", () => {
|
|
545
|
-
it("should broadcast messages to all subscribers when no ID is provided", (done) => {
|
|
546
|
-
const signal = new Signal<string>();
|
|
547
|
-
const mockCallback = jest.fn();
|
|
548
|
-
|
|
549
|
-
signal.subscribe(mockCallback);
|
|
550
|
-
signal.subscribe(mockCallback);
|
|
551
|
-
|
|
552
|
-
signal.ping("test message");
|
|
553
|
-
|
|
554
|
-
setImmediate(() => {
|
|
555
|
-
expect(mockCallback).toHaveBeenCalledTimes(2);
|
|
556
|
-
expect(mockCallback).toHaveBeenCalledWith("test message");
|
|
557
|
-
done();
|
|
558
|
-
});
|
|
559
|
-
});
|
|
560
|
-
|
|
561
|
-
it("should send messages only to subscribers with the specific ID", (done) => {
|
|
562
|
-
const signal = new Signal<string>();
|
|
563
|
-
const mockCallbackWithId = jest.fn();
|
|
564
|
-
const mockCallbackWithoutId = jest.fn();
|
|
565
|
-
|
|
566
|
-
signal.subscribe(mockCallbackWithId, "123");
|
|
567
|
-
signal.subscribe(mockCallbackWithoutId);
|
|
568
|
-
|
|
569
|
-
signal.ping("ID specific message", "123");
|
|
570
|
-
|
|
571
|
-
setImmediate(() => {
|
|
572
|
-
expect(mockCallbackWithId).toHaveBeenCalledTimes(1);
|
|
573
|
-
expect(mockCallbackWithId).toHaveBeenCalledWith("ID specific message");
|
|
574
|
-
expect(mockCallbackWithoutId).toHaveBeenCalledTimes(0);
|
|
575
|
-
done();
|
|
576
|
-
});
|
|
577
|
-
});
|
|
578
|
-
|
|
579
|
-
it("should not notify subscribers with different IDs", (done) => {
|
|
580
|
-
const signal = new Signal<string>();
|
|
581
|
-
const mockCallbackId123 = jest.fn();
|
|
582
|
-
const mockCallbackId456 = jest.fn();
|
|
583
|
-
|
|
584
|
-
signal.subscribe(mockCallbackId123, "123");
|
|
585
|
-
signal.subscribe(mockCallbackId456, "456");
|
|
586
|
-
|
|
587
|
-
signal.ping("Message for 123", "123");
|
|
588
|
-
|
|
589
|
-
setImmediate(() => {
|
|
590
|
-
expect(mockCallbackId123).toHaveBeenCalledTimes(1);
|
|
591
|
-
expect(mockCallbackId123).toHaveBeenCalledWith("Message for 123");
|
|
592
|
-
expect(mockCallbackId456).toHaveBeenCalledTimes(0);
|
|
593
|
-
done();
|
|
594
|
-
});
|
|
595
|
-
});
|
|
596
|
-
|
|
597
|
-
it("should notify all subscribers, including those with specific IDs, when pinging without an ID", (done) => {
|
|
598
|
-
const signal = new Signal<string>();
|
|
599
|
-
const mockCallback = jest.fn();
|
|
600
|
-
const mockCallbackWithId = jest.fn();
|
|
601
|
-
|
|
602
|
-
// Subscribe one callback without ID (for general broadcast)
|
|
603
|
-
signal.subscribe(mockCallback);
|
|
604
|
-
// Subscribe another callback with a specific ID
|
|
605
|
-
signal.subscribe(mockCallbackWithId, "123");
|
|
606
|
-
|
|
607
|
-
// Ping without specifying an ID should notify both subscribers
|
|
608
|
-
signal.ping("broadcast message");
|
|
609
|
-
|
|
610
|
-
setImmediate(() => {
|
|
611
|
-
// Both callbacks should be called once
|
|
612
|
-
expect(mockCallback).toHaveBeenCalledTimes(1);
|
|
613
|
-
expect(mockCallback).toHaveBeenCalledWith("broadcast message");
|
|
614
|
-
expect(mockCallbackWithId).toHaveBeenCalledTimes(1);
|
|
615
|
-
expect(mockCallbackWithId).toHaveBeenCalledWith("broadcast message");
|
|
616
|
-
done();
|
|
617
|
-
});
|
|
618
|
-
});
|
|
619
|
-
});
|
|
620
|
-
|
|
621
|
-
/*
|
|
622
|
-
* TODO:
|
|
623
|
-
* - test react hooks
|
|
624
|
-
* - test subscriptions
|
|
625
|
-
*/
|