| /** | |
| * Mutable reactive references for local, in-memory state. | |
| * | |
| * `AtomRef` provides small observable state cells that can be read, updated, | |
| * mapped, and subscribed to without going through an `AtomRegistry`. Mutable | |
| * refs can also create refs for nested properties. The module also provides a | |
| * collection helper that stores item refs and notifies subscribers when items are | |
| * inserted, removed, or changed. | |
| * | |
| * @since 4.0.0 | |
| */ | |
| import * as Equal from "../../Equal.js"; | |
| import * as Hash from "../../Hash.js"; | |
| /** | |
| * The runtime type id used to identify `AtomRef` values. | |
| * | |
| * @category type IDs | |
| * @since 4.0.0 | |
| */ | |
| export const TypeId = "~effect/reactivity/AtomRef"; | |
| /** | |
| * Creates a mutable reactive reference initialized with the supplied value. | |
| * | |
| * @category constructors | |
| * @since 4.0.0 | |
| */ | |
| export const make = value => new AtomRefImpl(value); | |
| /** | |
| * Creates a reactive collection from an iterable of initial item values. | |
| * | |
| * **Details** | |
| * | |
| * Each item is wrapped in an `AtomRef`, and changes to item refs notify the | |
| * collection subscribers. | |
| * | |
| * @category constructors | |
| * @since 4.0.0 | |
| */ | |
| export const collection = items => new CollectionImpl(items); | |
| const keyState = { | |
| count: 0, | |
| generate() { | |
| return `AtomRef-${this.count++}`; | |
| } | |
| }; | |
| class ReadonlyRefImpl { | |
| [TypeId]; | |
| key = /*#__PURE__*/keyState.generate(); | |
| value; | |
| constructor(value) { | |
| this[TypeId] = TypeId; | |
| this.value = value; | |
| } | |
| [Equal.symbol](that) { | |
| return Equal.equals(this.value, that.value); | |
| } | |
| [Hash.symbol]() { | |
| return Hash.hash(this.value); | |
| } | |
| listeners = null; | |
| notify(a) { | |
| let listener = this.listeners; | |
| while (listener !== null) { | |
| listener.f(a); | |
| listener = listener.next; | |
| } | |
| } | |
| subscribe(f) { | |
| const listener = { | |
| f, | |
| prev: null, | |
| next: this.listeners | |
| }; | |
| if (this.listeners) { | |
| this.listeners.prev = listener; | |
| } | |
| this.listeners = listener; | |
| return () => { | |
| if (this.listeners === listener) { | |
| this.listeners = listener.next; | |
| } | |
| if (listener.prev) { | |
| listener.prev.next = listener.next; | |
| } | |
| if (listener.next) { | |
| listener.next.prev = listener.prev; | |
| } | |
| }; | |
| } | |
| map(f) { | |
| return new MapRefImpl(this, f); | |
| } | |
| } | |
| class AtomRefImpl extends ReadonlyRefImpl { | |
| prop(prop) { | |
| return new PropRefImpl(this, prop); | |
| } | |
| set(value) { | |
| if (Equal.equals(value, this.value)) { | |
| return this; | |
| } | |
| this.value = value; | |
| this.notify(value); | |
| return this; | |
| } | |
| update(f) { | |
| return this.set(f(this.value)); | |
| } | |
| } | |
| class MapRefImpl { | |
| [TypeId]; | |
| key = /*#__PURE__*/keyState.generate(); | |
| parent; | |
| transform; | |
| constructor(parent, transform) { | |
| this[TypeId] = TypeId; | |
| this.parent = parent; | |
| this.transform = transform; | |
| } | |
| [Equal.symbol](that) { | |
| return Equal.equals(this.value, that.value); | |
| } | |
| [Hash.symbol]() { | |
| return Hash.hash(this.value); | |
| } | |
| get value() { | |
| return this.transform(this.parent.value); | |
| } | |
| subscribe(f) { | |
| let previous = this.transform(this.parent.value); | |
| return this.parent.subscribe(a => { | |
| const next = this.transform(a); | |
| if (Equal.equals(next, previous)) { | |
| return; | |
| } | |
| previous = next; | |
| f(next); | |
| }); | |
| } | |
| map(f) { | |
| return new MapRefImpl(this, f); | |
| } | |
| } | |
| class PropRefImpl { | |
| [TypeId]; | |
| key = /*#__PURE__*/keyState.generate(); | |
| previous; | |
| parent; | |
| _prop; | |
| constructor(parent, _prop) { | |
| this[TypeId] = TypeId; | |
| this.parent = parent; | |
| this._prop = _prop; | |
| this.previous = parent.value[_prop]; | |
| } | |
| [Equal.symbol](that) { | |
| return Equal.equals(this.value, that.value); | |
| } | |
| [Hash.symbol]() { | |
| return Hash.hash(this.value); | |
| } | |
| get value() { | |
| if (this.parent.value && this._prop in this.parent.value) { | |
| this.previous = this.parent.value[this._prop]; | |
| } | |
| return this.previous; | |
| } | |
| subscribe(f) { | |
| let previous = this.value; | |
| return this.parent.subscribe(a => { | |
| if (!a || !(this._prop in a)) { | |
| return; | |
| } | |
| const next = a[this._prop]; | |
| if (Equal.equals(next, previous)) { | |
| return; | |
| } | |
| previous = next; | |
| f(next); | |
| }); | |
| } | |
| map(f) { | |
| return new MapRefImpl(this, f); | |
| } | |
| prop(prop) { | |
| return new PropRefImpl(this, prop); | |
| } | |
| set(value) { | |
| if (Array.isArray(this.parent.value)) { | |
| const newArray = this.parent.value.slice(); | |
| newArray[this._prop] = value; | |
| this.parent.set(newArray); | |
| } else { | |
| this.parent.set({ | |
| ...this.parent.value, | |
| [this._prop]: value | |
| }); | |
| } | |
| return this; | |
| } | |
| update(f) { | |
| if (Array.isArray(this.parent.value)) { | |
| const newArray = this.parent.value.slice(); | |
| newArray[this._prop] = f(this.parent.value[this._prop]); | |
| this.parent.set(newArray); | |
| } else { | |
| this.parent.set({ | |
| ...this.parent.value, | |
| [this._prop]: f(this.parent.value[this._prop]) | |
| }); | |
| } | |
| return this; | |
| } | |
| } | |
| class CollectionImpl extends ReadonlyRefImpl { | |
| constructor(items) { | |
| super([]); | |
| for (const item of items) { | |
| this.value.push(this.makeRef(item)); | |
| } | |
| } | |
| makeRef(value) { | |
| const ref = new AtomRefImpl(value); | |
| const notify = value => { | |
| ref.notify(value); | |
| this.notify(this.value); | |
| }; | |
| return new Proxy(ref, { | |
| get(target, p, _receiver) { | |
| if (p === "notify") { | |
| return notify; | |
| } | |
| return target[p]; | |
| } | |
| }); | |
| } | |
| push(item) { | |
| const ref = this.makeRef(item); | |
| this.value.push(ref); | |
| this.notify(this.value); | |
| return this; | |
| } | |
| insertAt(index, item) { | |
| const ref = this.makeRef(item); | |
| this.value.splice(index, 0, ref); | |
| this.notify(this.value); | |
| return this; | |
| } | |
| remove(ref) { | |
| const index = this.value.indexOf(ref); | |
| if (index !== -1) { | |
| this.value.splice(index, 1); | |
| this.notify(this.value); | |
| } | |
| return this; | |
| } | |
| toArray() { | |
| return this.value.map(ref => ref.value); | |
| } | |
| } | |
| //# sourceMappingURL=AtomRef.js.map |
Xet Storage Details
- Size:
- 6.01 kB
- Xet hash:
- 20464a1c55a6de2db8aae88d4dcb9b6afda0ccdcc51925d760c109b964ee089f
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.