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/dist/index.mjs
ADDED
|
@@ -0,0 +1,423 @@
|
|
|
1
|
+
function _extends() {
|
|
2
|
+
return _extends = Object.assign ? Object.assign.bind() : function (n) {
|
|
3
|
+
for (var e = 1; e < arguments.length; e++) {
|
|
4
|
+
var t = arguments[e];
|
|
5
|
+
for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
|
|
6
|
+
}
|
|
7
|
+
return n;
|
|
8
|
+
}, _extends.apply(null, arguments);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const noop = () => {};
|
|
12
|
+
function createSubscription(unsubscribe) {
|
|
13
|
+
let closed = false;
|
|
14
|
+
return {
|
|
15
|
+
unsubscribe: () => {
|
|
16
|
+
if (closed) return;
|
|
17
|
+
closed = true;
|
|
18
|
+
unsubscribe();
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function normalizeSubscription(subscription) {
|
|
23
|
+
if (typeof subscription === "function") {
|
|
24
|
+
return createSubscription(subscription);
|
|
25
|
+
}
|
|
26
|
+
if (subscription && typeof subscription.unsubscribe === "function") {
|
|
27
|
+
return createSubscription(() => subscription.unsubscribe());
|
|
28
|
+
}
|
|
29
|
+
return createSubscription(noop);
|
|
30
|
+
}
|
|
31
|
+
function isAtomSource(value) {
|
|
32
|
+
return value != null && typeof value === "object" && typeof value.subscribe === "function";
|
|
33
|
+
}
|
|
34
|
+
function readAtomSourceValue(source) {
|
|
35
|
+
if (typeof source.getValue === "function") {
|
|
36
|
+
return source.getValue();
|
|
37
|
+
}
|
|
38
|
+
if (typeof source.value === "function") {
|
|
39
|
+
return source.value();
|
|
40
|
+
}
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
function toListener(observer) {
|
|
44
|
+
if (typeof observer === "function") {
|
|
45
|
+
return observer;
|
|
46
|
+
}
|
|
47
|
+
if (observer && typeof observer.next === "function") {
|
|
48
|
+
return value => observer.next == null ? void 0 : observer.next(value);
|
|
49
|
+
}
|
|
50
|
+
return noop;
|
|
51
|
+
}
|
|
52
|
+
function notifyListeners(listeners, value) {
|
|
53
|
+
const errors = [];
|
|
54
|
+
for (const listener of Array.from(listeners)) {
|
|
55
|
+
try {
|
|
56
|
+
listener(value);
|
|
57
|
+
} catch (error) {
|
|
58
|
+
errors.push(error);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (errors.length === 1) {
|
|
62
|
+
throw errors[0];
|
|
63
|
+
}
|
|
64
|
+
if (errors.length > 1) {
|
|
65
|
+
throw new AggregateError(errors, "Multiple atom subscribers failed");
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
class ValueStore {
|
|
69
|
+
constructor(value) {
|
|
70
|
+
this._listeners = [];
|
|
71
|
+
this._value = value;
|
|
72
|
+
}
|
|
73
|
+
getValue() {
|
|
74
|
+
return this._value;
|
|
75
|
+
}
|
|
76
|
+
setValue(value) {
|
|
77
|
+
this._value = value;
|
|
78
|
+
}
|
|
79
|
+
next(value) {
|
|
80
|
+
this._value = value;
|
|
81
|
+
notifyListeners(this._listeners, value);
|
|
82
|
+
}
|
|
83
|
+
subscribe(observer, options = {}) {
|
|
84
|
+
const listener = toListener(observer);
|
|
85
|
+
this._listeners.push(listener);
|
|
86
|
+
if (options.emitImmediately !== false) {
|
|
87
|
+
listener(this._value);
|
|
88
|
+
}
|
|
89
|
+
return createSubscription(() => {
|
|
90
|
+
const index = this._listeners.indexOf(listener);
|
|
91
|
+
if (index >= 0) {
|
|
92
|
+
this._listeners.splice(index, 1);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Comparator used to decide whether an atom's value has changed.
|
|
100
|
+
*
|
|
101
|
+
* An atom notifies subscribers only when `equals(previous, next)` returns
|
|
102
|
+
* `false`. The default for every atom is {@link Object.is} (value equality for
|
|
103
|
+
* primitives, reference identity for objects/arrays). Supply a content
|
|
104
|
+
* comparator to dedup by data, or `() => false` to force every update to emit.
|
|
105
|
+
*/
|
|
106
|
+
|
|
107
|
+
class ReadOnlyAtom {
|
|
108
|
+
/**
|
|
109
|
+
* @param options.equals Comparator deciding when the value has changed.
|
|
110
|
+
* Defaults to {@link Object.is}. Subscribers are notified only when it
|
|
111
|
+
* returns `false`.
|
|
112
|
+
*/
|
|
113
|
+
constructor(_value, dependency, options) {
|
|
114
|
+
var _options$equals;
|
|
115
|
+
this._subscriptions = [];
|
|
116
|
+
this._dependency = null;
|
|
117
|
+
this._dependencySubscription = null;
|
|
118
|
+
this._subscriberCount = 0;
|
|
119
|
+
this._equals = (_options$equals = options == null ? void 0 : options.equals) != null ? _options$equals : Object.is;
|
|
120
|
+
if (dependency) {
|
|
121
|
+
this._dependency = dependency;
|
|
122
|
+
this._store = new ValueStore(_value);
|
|
123
|
+
} else if (isAtomSource(_value)) {
|
|
124
|
+
this._store = new ValueStore(readAtomSourceValue(_value));
|
|
125
|
+
this._addSubscription(_value.subscribe(value => {
|
|
126
|
+
this._next(value);
|
|
127
|
+
}));
|
|
128
|
+
} else {
|
|
129
|
+
this._store = new ValueStore(_value);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Create a read-only atom whose value is derived from this atom.
|
|
135
|
+
*
|
|
136
|
+
* By default the derived atom notifies subscribers only when its computed
|
|
137
|
+
* output differs by {@link Object.is}. Pass `options.equals` to dedup by
|
|
138
|
+
* content (useful when `deriveFn` returns a fresh object/array each time), or
|
|
139
|
+
* `equals: () => false` to re-emit on every parent update.
|
|
140
|
+
*/
|
|
141
|
+
derive(deriveFn, options) {
|
|
142
|
+
let index = 0;
|
|
143
|
+
let hasCachedInput = false;
|
|
144
|
+
let cachedInput;
|
|
145
|
+
let cachedValue;
|
|
146
|
+
const getSnapshot = (force = false) => {
|
|
147
|
+
const input = this.value();
|
|
148
|
+
if (force || !hasCachedInput || !Object.is(cachedInput, input)) {
|
|
149
|
+
cachedInput = input;
|
|
150
|
+
cachedValue = deriveFn(input, index++);
|
|
151
|
+
hasCachedInput = true;
|
|
152
|
+
}
|
|
153
|
+
return cachedValue;
|
|
154
|
+
};
|
|
155
|
+
return new ReadOnlyAtom(getSnapshot(), {
|
|
156
|
+
getSnapshot,
|
|
157
|
+
subscribe: onDependencyChange => this._subscribe(onDependencyChange, {
|
|
158
|
+
emitImmediately: false
|
|
159
|
+
})
|
|
160
|
+
}, options);
|
|
161
|
+
}
|
|
162
|
+
subscribe(observer) {
|
|
163
|
+
return this._subscribe(observer);
|
|
164
|
+
}
|
|
165
|
+
value() {
|
|
166
|
+
if (this._dependency) {
|
|
167
|
+
this._refresh(false);
|
|
168
|
+
}
|
|
169
|
+
return this._store.getValue();
|
|
170
|
+
}
|
|
171
|
+
dispose() {
|
|
172
|
+
var _this$_dependencySubs;
|
|
173
|
+
(_this$_dependencySubs = this._dependencySubscription) == null || _this$_dependencySubs.unsubscribe();
|
|
174
|
+
this._dependencySubscription = null;
|
|
175
|
+
this._subscriberCount = 0;
|
|
176
|
+
for (const subscription of this._subscriptions.splice(0)) {
|
|
177
|
+
subscription.unsubscribe();
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
get(key) {
|
|
181
|
+
const val = this.value();
|
|
182
|
+
return val == null ? void 0 : val[key];
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Create a read-only atom that tracks `key` on this atom's value.
|
|
187
|
+
*
|
|
188
|
+
* By default the selected atom notifies subscribers only when the selected
|
|
189
|
+
* value differs by {@link Object.is}. Pass `options.equals` to dedup by
|
|
190
|
+
* content instead.
|
|
191
|
+
*/
|
|
192
|
+
select(key, options) {
|
|
193
|
+
const getSnapshot = () => {
|
|
194
|
+
const value = this.value();
|
|
195
|
+
return value == null ? void 0 : value[key];
|
|
196
|
+
};
|
|
197
|
+
return new ReadOnlyAtom(getSnapshot(), {
|
|
198
|
+
getSnapshot,
|
|
199
|
+
subscribe: onDependencyChange => this._subscribe(onDependencyChange, {
|
|
200
|
+
emitImmediately: false
|
|
201
|
+
})
|
|
202
|
+
}, options);
|
|
203
|
+
}
|
|
204
|
+
_refresh(emit, force = false) {
|
|
205
|
+
if (!this._dependency) {
|
|
206
|
+
return this._store.getValue();
|
|
207
|
+
}
|
|
208
|
+
const previousValue = this._store.getValue();
|
|
209
|
+
const nextValue = this._dependency.getSnapshot(force);
|
|
210
|
+
const shouldNotify = emit && !this._equals(previousValue, nextValue);
|
|
211
|
+
if (shouldNotify) {
|
|
212
|
+
this._store.next(nextValue);
|
|
213
|
+
} else {
|
|
214
|
+
this._store.setValue(nextValue);
|
|
215
|
+
}
|
|
216
|
+
return nextValue;
|
|
217
|
+
}
|
|
218
|
+
_retainDependency() {
|
|
219
|
+
if (!this._dependency) {
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
this._subscriberCount += 1;
|
|
223
|
+
if (this._subscriberCount === 1) {
|
|
224
|
+
this._dependencySubscription = normalizeSubscription(this._dependency.subscribe(() => {
|
|
225
|
+
this._refresh(true, true);
|
|
226
|
+
}));
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
_releaseDependency() {
|
|
230
|
+
if (!this._dependency || this._subscriberCount === 0) {
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
this._subscriberCount -= 1;
|
|
234
|
+
if (this._subscriberCount === 0) {
|
|
235
|
+
var _this$_dependencySubs2;
|
|
236
|
+
(_this$_dependencySubs2 = this._dependencySubscription) == null || _this$_dependencySubs2.unsubscribe();
|
|
237
|
+
this._dependencySubscription = null;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/** @internal */
|
|
242
|
+
_next(value) {
|
|
243
|
+
const previousValue = this._store.getValue();
|
|
244
|
+
if (this._equals(previousValue, value)) {
|
|
245
|
+
this._store.setValue(value);
|
|
246
|
+
} else {
|
|
247
|
+
this._store.next(value);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/** @internal */
|
|
252
|
+
_subscribe(observer, options) {
|
|
253
|
+
if (!this._dependency) {
|
|
254
|
+
return this._store.subscribe(observer, options);
|
|
255
|
+
}
|
|
256
|
+
this._refresh(false);
|
|
257
|
+
let subscription;
|
|
258
|
+
try {
|
|
259
|
+
this._retainDependency();
|
|
260
|
+
subscription = this._store.subscribe(observer, options);
|
|
261
|
+
} catch (error) {
|
|
262
|
+
this._releaseDependency();
|
|
263
|
+
throw error;
|
|
264
|
+
}
|
|
265
|
+
return createSubscription(() => {
|
|
266
|
+
subscription.unsubscribe();
|
|
267
|
+
this._releaseDependency();
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/** @internal */
|
|
272
|
+
_addSubscription(subscription) {
|
|
273
|
+
const normalized = normalizeSubscription(subscription);
|
|
274
|
+
this._subscriptions.push(normalized);
|
|
275
|
+
return normalized;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
class BaseAtom extends ReadOnlyAtom {
|
|
279
|
+
next(nextVal) {
|
|
280
|
+
this._next(nextVal);
|
|
281
|
+
}
|
|
282
|
+
set(nextKey, nextValue) {
|
|
283
|
+
const currentValue = this.value();
|
|
284
|
+
if (currentValue == null || typeof currentValue !== "object") {
|
|
285
|
+
throw new TypeError("Atom.set can only be used with object values");
|
|
286
|
+
}
|
|
287
|
+
this._next(_extends({}, currentValue, {
|
|
288
|
+
[nextKey]: nextValue
|
|
289
|
+
}));
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
class NullableBaseAtom extends BaseAtom {
|
|
293
|
+
constructor(_value, options) {
|
|
294
|
+
super(_value, undefined, options);
|
|
295
|
+
}
|
|
296
|
+
next(nextVal) {
|
|
297
|
+
this._next(nextVal);
|
|
298
|
+
}
|
|
299
|
+
reset() {
|
|
300
|
+
this._next(undefined);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
class ArrayAtom extends BaseAtom {
|
|
304
|
+
constructor(initialValue, options) {
|
|
305
|
+
if (initialValue === undefined) {
|
|
306
|
+
super([], undefined, options);
|
|
307
|
+
} else {
|
|
308
|
+
super(initialValue, undefined, options);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
push(nextVal) {
|
|
312
|
+
this._next([...this.value(), nextVal]);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Options for the {@link Atom} factory. `readOnly` produces a
|
|
318
|
+
* {@link ReadOnlyAtom}; `equals` sets the change comparator (defaults to
|
|
319
|
+
* {@link Object.is}).
|
|
320
|
+
*/
|
|
321
|
+
|
|
322
|
+
// Legacy positional `readOnly` form.
|
|
323
|
+
|
|
324
|
+
// Options-object form.
|
|
325
|
+
|
|
326
|
+
function Atom(_value, optionsOrReadOnly) {
|
|
327
|
+
const factoryOptions = typeof optionsOrReadOnly === "boolean" ? {
|
|
328
|
+
readOnly: optionsOrReadOnly
|
|
329
|
+
} : optionsOrReadOnly != null ? optionsOrReadOnly : {};
|
|
330
|
+
const {
|
|
331
|
+
readOnly = false,
|
|
332
|
+
equals
|
|
333
|
+
} = factoryOptions;
|
|
334
|
+
const atomOptions = equals ? {
|
|
335
|
+
equals
|
|
336
|
+
} : undefined;
|
|
337
|
+
if (readOnly) {
|
|
338
|
+
return new ReadOnlyAtom(_value, undefined, atomOptions);
|
|
339
|
+
}
|
|
340
|
+
if (isAtomSource(_value)) {
|
|
341
|
+
const sourceValue = readAtomSourceValue(_value);
|
|
342
|
+
if (Array.isArray(sourceValue)) {
|
|
343
|
+
return new ArrayAtom(_value, atomOptions);
|
|
344
|
+
}
|
|
345
|
+
return new BaseAtom(_value, undefined, atomOptions);
|
|
346
|
+
}
|
|
347
|
+
if (Array.isArray(_value)) {
|
|
348
|
+
return new ArrayAtom(_value, atomOptions);
|
|
349
|
+
}
|
|
350
|
+
if (_value == null) {
|
|
351
|
+
return new NullableBaseAtom(undefined, atomOptions);
|
|
352
|
+
}
|
|
353
|
+
return new BaseAtom(_value, undefined, atomOptions);
|
|
354
|
+
}
|
|
355
|
+
Atom.combine = (...atoms) => {
|
|
356
|
+
const getSnapshot = () => atoms.map(atom => atom.value());
|
|
357
|
+
return new ReadOnlyAtom(getSnapshot(), {
|
|
358
|
+
getSnapshot,
|
|
359
|
+
subscribe: onDependencyChange => {
|
|
360
|
+
const subscriptions = atoms.map(atom => atom._subscribe(onDependencyChange, {
|
|
361
|
+
emitImmediately: false
|
|
362
|
+
}));
|
|
363
|
+
return () => {
|
|
364
|
+
for (const subscription of subscriptions) {
|
|
365
|
+
subscription.unsubscribe();
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
});
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
const hydratedAtomsSet = new WeakSet();
|
|
373
|
+
function hydrateAtoms(values, options) {
|
|
374
|
+
for (const [atom, value] of values) {
|
|
375
|
+
if (!hydratedAtomsSet.has(atom) || options != null && options.force) {
|
|
376
|
+
hydratedAtomsSet.add(atom);
|
|
377
|
+
atom.next(value);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
class Signal {
|
|
383
|
+
constructor() {
|
|
384
|
+
this._listeners = [];
|
|
385
|
+
this._listenersById = new Map();
|
|
386
|
+
}
|
|
387
|
+
ping(value, id) {
|
|
388
|
+
if (id && this._listenersById.has(id)) {
|
|
389
|
+
notifyListeners(this._listenersById.get(id), value);
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
notifyListeners(this._listeners, value);
|
|
393
|
+
for (const listeners of this._listenersById.values()) {
|
|
394
|
+
notifyListeners(listeners, value);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
subscribe(callback, id) {
|
|
398
|
+
var _this$_listenersById$;
|
|
399
|
+
if (!id) {
|
|
400
|
+
this._listeners.push(callback);
|
|
401
|
+
return createSubscription(() => {
|
|
402
|
+
removeListener(this._listeners, callback);
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
const listeners = (_this$_listenersById$ = this._listenersById.get(id)) != null ? _this$_listenersById$ : [];
|
|
406
|
+
listeners.push(callback);
|
|
407
|
+
this._listenersById.set(id, listeners);
|
|
408
|
+
return createSubscription(() => {
|
|
409
|
+
removeListener(listeners, callback);
|
|
410
|
+
if (listeners.length === 0) {
|
|
411
|
+
this._listenersById.delete(id);
|
|
412
|
+
}
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
function removeListener(listeners, callback) {
|
|
417
|
+
const index = listeners.indexOf(callback);
|
|
418
|
+
if (index >= 0) {
|
|
419
|
+
listeners.splice(index, 1);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
export { Atom, Signal, hydrateAtoms };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var react = require('react');
|
|
4
|
+
|
|
5
|
+
function useAtom(atom) {
|
|
6
|
+
return react.useSyncExternalStore(function (onStoreChange) {
|
|
7
|
+
var subscribed = false;
|
|
8
|
+
var subscription = atom.subscribe(function () {
|
|
9
|
+
if (subscribed) {
|
|
10
|
+
onStoreChange();
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
subscribed = true;
|
|
14
|
+
return function () {
|
|
15
|
+
subscription.unsubscribe();
|
|
16
|
+
};
|
|
17
|
+
}, function () {
|
|
18
|
+
return atom.value();
|
|
19
|
+
}, function () {
|
|
20
|
+
return atom.value();
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function useSignal(signal, callback, id) {
|
|
25
|
+
react.useEffect(function () {
|
|
26
|
+
// Assuming the signal might not have an initial value method like `atom.value()`,
|
|
27
|
+
// If your signal class has a method to get the current/latest value, use it here to initialize.
|
|
28
|
+
|
|
29
|
+
var subscription;
|
|
30
|
+
if (callback) {
|
|
31
|
+
subscription = signal.subscribe(callback, id);
|
|
32
|
+
}
|
|
33
|
+
return function () {
|
|
34
|
+
if (subscription) {
|
|
35
|
+
subscription.unsubscribe();
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
}, [signal, callback, id]);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function useSelectAtom(atom, key) {
|
|
42
|
+
var selectedAtom = react.useMemo(function () {
|
|
43
|
+
return atom.select(key);
|
|
44
|
+
}, [atom, key]);
|
|
45
|
+
return useAtom(selectedAtom);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
exports.useAtom = useAtom;
|
|
49
|
+
exports.useSelectAtom = useSelectAtom;
|
|
50
|
+
exports.useSignal = useSignal;
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
export { Atom } from "./Atom";
|
|
2
1
|
export { useAtom } from "./useAtom";
|
|
3
2
|
export { useSignal } from "./useSignal";
|
|
4
3
|
export { useSelectAtom } from "./useSelectAtom";
|
|
5
|
-
|
|
6
|
-
export { Signal } from "./Signal";
|
|
4
|
+
//# sourceMappingURL=react.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/react.mjs
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { useSyncExternalStore, useEffect, useMemo } from 'react';
|
|
2
|
+
|
|
3
|
+
function useAtom(atom) {
|
|
4
|
+
return useSyncExternalStore(onStoreChange => {
|
|
5
|
+
let subscribed = false;
|
|
6
|
+
const subscription = atom.subscribe(() => {
|
|
7
|
+
if (subscribed) {
|
|
8
|
+
onStoreChange();
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
subscribed = true;
|
|
12
|
+
return () => {
|
|
13
|
+
subscription.unsubscribe();
|
|
14
|
+
};
|
|
15
|
+
}, () => atom.value(), () => atom.value());
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function useSignal(signal, callback, id) {
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
// Assuming the signal might not have an initial value method like `atom.value()`,
|
|
21
|
+
// If your signal class has a method to get the current/latest value, use it here to initialize.
|
|
22
|
+
|
|
23
|
+
let subscription;
|
|
24
|
+
if (callback) {
|
|
25
|
+
subscription = signal.subscribe(callback, id);
|
|
26
|
+
}
|
|
27
|
+
return () => {
|
|
28
|
+
if (subscription) {
|
|
29
|
+
subscription.unsubscribe();
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
}, [signal, callback, id]);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function useSelectAtom(atom, key) {
|
|
36
|
+
const selectedAtom = useMemo(() => atom.select(key), [atom, key]);
|
|
37
|
+
return useAtom(selectedAtom);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export { useAtom, useSelectAtom, useSignal };
|
package/dist/store.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export type AtomListener<T> = (value: T) => void;
|
|
2
|
+
export type AtomSubscription = {
|
|
3
|
+
unsubscribe: () => void;
|
|
4
|
+
};
|
|
5
|
+
export type AtomObserver<T> = AtomListener<T> | {
|
|
6
|
+
next?: AtomListener<T>;
|
|
7
|
+
};
|
|
8
|
+
export type AtomSource<T> = {
|
|
9
|
+
subscribe: (observer: AtomObserver<T>) => AtomSubscription | (() => void) | void;
|
|
10
|
+
getValue?: () => T;
|
|
11
|
+
value?: () => T;
|
|
12
|
+
};
|
|
13
|
+
export declare function createSubscription(unsubscribe: () => void): AtomSubscription;
|
|
14
|
+
export declare function normalizeSubscription(subscription: AtomSubscription | (() => void) | void): AtomSubscription;
|
|
15
|
+
export declare function isAtomSource<T = unknown>(value: unknown): value is AtomSource<T>;
|
|
16
|
+
export declare function readAtomSourceValue<T>(source: AtomSource<T>): T;
|
|
17
|
+
export declare function toListener<T>(observer: AtomObserver<T>): AtomListener<T>;
|
|
18
|
+
export declare function notifyListeners<T>(listeners: Iterable<AtomListener<T>>, value: T): void;
|
|
19
|
+
export declare class ValueStore<T> {
|
|
20
|
+
private _value;
|
|
21
|
+
private _listeners;
|
|
22
|
+
constructor(value: T);
|
|
23
|
+
getValue(): T;
|
|
24
|
+
setValue(value: T): void;
|
|
25
|
+
next(value: T): void;
|
|
26
|
+
subscribe(observer: AtomObserver<T>, options?: {
|
|
27
|
+
emitImmediately?: boolean;
|
|
28
|
+
}): AtomSubscription;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;AAEjD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,WAAW,EAAE,MAAM,IAAI,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,YAAY,CAAC,CAAC,IACtB,YAAY,CAAC,CAAC,CAAC,GACf;IACE,IAAI,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;CACxB,CAAC;AAEN,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI;IAC1B,SAAS,EAAE,CACT,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,KACtB,gBAAgB,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAC,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC,CAAC;CACjB,CAAC;AAIF,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,IAAI,GAAG,gBAAgB,CAU5E;AAED,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,gBAAgB,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,GACnD,gBAAgB,CAUlB;AAED,wBAAgB,YAAY,CAAC,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,UAAU,CAAC,CAAC,CAAC,CAMhF;AAED,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAU/D;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,CAUxE;AAED,wBAAgB,eAAe,CAAC,CAAC,EAC/B,SAAS,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EACpC,KAAK,EAAE,CAAC,QAmBT;AAED,qBAAa,UAAU,CAAC,CAAC;IACvB,OAAO,CAAC,MAAM,CAAI;IAClB,OAAO,CAAC,UAAU,CAAyB;gBAE/B,KAAK,EAAE,CAAC;IAIpB,QAAQ;IAIR,QAAQ,CAAC,KAAK,EAAE,CAAC;IAIjB,IAAI,CAAC,KAAK,EAAE,CAAC;IAKb,SAAS,CACP,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,EACzB,OAAO,GAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAA;KAAO,GAC1C,gBAAgB;CAgBpB"}
|
package/dist/useAtom.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare function useAtom<T>(atom:
|
|
1
|
+
import { ReadOnlyAtom } from "./Atom";
|
|
2
|
+
export declare function useAtom<T>(atom: ReadOnlyAtom<T>): T;
|
|
3
3
|
//# sourceMappingURL=useAtom.d.ts.map
|
package/dist/useAtom.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAtom.d.ts","sourceRoot":"","sources":["../src/useAtom.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"useAtom.d.ts","sourceRoot":"","sources":["../src/useAtom.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,wBAAgB,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAkBnD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useHydrateAtoms.d.ts","sourceRoot":"","sources":["../src/useHydrateAtoms.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useHydrateAtoms.d.ts","sourceRoot":"","sources":["../src/useHydrateAtoms.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAgB,MAAM,QAAQ,CAAC;AAIlE,wBAAgB,YAAY,CAC1B,MAAM,EAAE,SAAS,CAAC,gBAAgB,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,EAAE,EAC/D,OAAO,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,QAQ9B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useSelectAtom.d.ts","sourceRoot":"","sources":["../src/useSelectAtom.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"useSelectAtom.d.ts","sourceRoot":"","sources":["../src/useSelectAtom.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAGlE,wBAAgB,aAAa,CAC3B,CAAC,SACG;KACG,GAAG,IAAI,CAAC,GAAG,CAAC;CACd,EACL,CAAC,SAAS,MAAM,CAAC,EACjB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EACR,IAAI,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAMzE"}
|
package/package.json
CHANGED
|
@@ -1,9 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "chem-rx",
|
|
3
|
-
"version": "0.0
|
|
4
|
-
"description": "react state primitives
|
|
5
|
-
"main": "dist/index.js",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "react state primitives with framework-agnostic atoms",
|
|
5
|
+
"main": "dist/index.cjs.js",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
6
7
|
"types": "dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist",
|
|
10
|
+
"README.md",
|
|
11
|
+
"CHANGELOG.md",
|
|
12
|
+
"LICENSE"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"prebuild": "rimraf dist",
|
|
16
|
+
"test": "jest",
|
|
17
|
+
"clean": "rm -rf ./dist",
|
|
18
|
+
"build": "pnpm run prebuild && tsc --emitDeclarationOnly && rollup -c",
|
|
19
|
+
"prepublishOnly": "pnpm run test && pnpm run build"
|
|
20
|
+
},
|
|
7
21
|
"repository": {
|
|
8
22
|
"type": "git",
|
|
9
23
|
"url": "git+https://github.com/dxu/chem-rx.git"
|
|
@@ -22,7 +36,6 @@
|
|
|
22
36
|
"@babel/preset-typescript": "^7.22.5",
|
|
23
37
|
"@rollup/plugin-babel": "^6.0.3",
|
|
24
38
|
"@rollup/plugin-node-resolve": "^15.1.0",
|
|
25
|
-
"@rollup/plugin-typescript": "^11.1.2",
|
|
26
39
|
"@types/jest": "^29.5.3",
|
|
27
40
|
"@types/react": "^18.2.20",
|
|
28
41
|
"jest": "^29.6.2",
|
|
@@ -31,22 +44,27 @@
|
|
|
31
44
|
"rollup-plugin-size-snapshot": "^0.12.0",
|
|
32
45
|
"rollup-plugin-typescript2": "^0.35.0",
|
|
33
46
|
"rollup-plugin-visualizer": "^5.9.2",
|
|
34
|
-
"rxjs": "^7.8.1",
|
|
35
47
|
"typescript": "^5.1.6"
|
|
36
48
|
},
|
|
37
49
|
"peerDependencies": {
|
|
38
|
-
"react": "^18.2.0"
|
|
39
|
-
|
|
50
|
+
"react": "^18.2.0"
|
|
51
|
+
},
|
|
52
|
+
"peerDependenciesMeta": {
|
|
53
|
+
"react": {
|
|
54
|
+
"optional": true
|
|
55
|
+
}
|
|
40
56
|
},
|
|
41
57
|
"exports": {
|
|
42
|
-
".":
|
|
58
|
+
".": {
|
|
59
|
+
"types": "./dist/index.d.ts",
|
|
60
|
+
"import": "./dist/index.mjs",
|
|
61
|
+
"require": "./dist/index.cjs.js"
|
|
62
|
+
},
|
|
63
|
+
"./react": {
|
|
64
|
+
"types": "./dist/react.d.ts",
|
|
65
|
+
"import": "./dist/react.mjs",
|
|
66
|
+
"require": "./dist/react.cjs.js"
|
|
67
|
+
},
|
|
43
68
|
"./index.cjs.js": "./dist/index.cjs.js"
|
|
44
|
-
},
|
|
45
|
-
"scripts": {
|
|
46
|
-
"prebuild": "rimraf dist",
|
|
47
|
-
"test": "jest",
|
|
48
|
-
"clean": "rm -rf ./dist",
|
|
49
|
-
"build": "pnpm run prebuild && rollup -c",
|
|
50
|
-
"bump": "pnpm run build && pnpm version patch"
|
|
51
69
|
}
|
|
52
|
-
}
|
|
70
|
+
}
|
package/.size-snapshot.json
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"index.js": {
|
|
3
|
-
"bundled": 2254,
|
|
4
|
-
"minified": 1146,
|
|
5
|
-
"gzipped": 529,
|
|
6
|
-
"treeshaked": {
|
|
7
|
-
"rollup": {
|
|
8
|
-
"code": 13,
|
|
9
|
-
"import_statements": 13
|
|
10
|
-
},
|
|
11
|
-
"webpack": {
|
|
12
|
-
"code": 997
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
},
|
|
16
|
-
"index.cjs.js": {
|
|
17
|
-
"bundled": 2625,
|
|
18
|
-
"minified": 1302,
|
|
19
|
-
"gzipped": 570
|
|
20
|
-
},
|
|
21
|
-
"index.iife.js": {
|
|
22
|
-
"bundled": 2825,
|
|
23
|
-
"minified": 1233,
|
|
24
|
-
"gzipped": 550
|
|
25
|
-
}
|
|
26
|
-
}
|