@fest-lib/object 0.1.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.
Files changed (4) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +423 -0
  3. package/dist/object.js +1717 -0
  4. package/package.json +75 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 unite-2.ts
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,423 @@
1
+ # Object.TS
2
+
3
+ <img src="https://img.shields.io/github/license/fest-live/object.ts?style=flat-square" alt="License"> <img src="https://img.shields.io/github/stars/fest-live/object.ts?style=flat-square" alt="Stars"> <img src="https://img.shields.io/github/last-commit/fest-live/object.ts?style=flat-square" alt="Last Commit">
4
+
5
+ [![npm version](https://img.shields.io/npm/v/object.ts?style=flat-square)](https://www.npmjs.com/package/@fest-lib/object.ts)
6
+ [![Build Status](https://img.shields.io/github/actions/workflow/status/fest-live/object.ts/ci.yml?branch=main&style=flat-square)](https://github.com/fest-live/object.ts/actions)
7
+ [![Coverage Status](https://img.shields.io/codecov/c/github/fest-live/object.ts?style=flat-square)](https://codecov.io/gh/fest-live/object.ts)
8
+
9
+ ---
10
+
11
+ **Object.ts** is a lightweight library providing reactive primitives and object utilities for JavaScript. It is a minor sibling of [`Uniform.TS`](https://github.com/fest-live/uniform.ts), originally created in early 2024 and partially revisited in 2025. The library is primarily used in internal projects and is designed to be compatible with modern reactive libraries.
12
+
13
+ The current version provides a comprehensive reactivity system with non-intrusive subscriptions, efficient change detection, and compatibility with modern JavaScript frameworks.
14
+
15
+ ## Table of Contents
16
+
17
+ - [Features](#features)
18
+ - [Installation](#installation)
19
+ - [Usage](#usage)
20
+ - [API Reference](#api-reference)
21
+ - [Reactivity](#reactivity)
22
+ - [DOM Utilities](#dom-utilities)
23
+ - [Related Projects](#related-projects)
24
+ - [License](#license)
25
+
26
+ ---
27
+
28
+ ## Features
29
+
30
+ - **Non-intrusive subscriptions:** Subscribers do not retain references to target objects.
31
+ - **Efficient reactivity:** Triggers only on actual value changes.
32
+ - **Compatibility:** Works with recent versions of popular reactive libraries.
33
+
34
+ ---
35
+
36
+ ## Usage & Examples
37
+
38
+ ### Reactivity (basics)
39
+
40
+ - **`observe(initial)`**
41
+ Creates a reactive primitive from an existing object, array, Set, or Map.
42
+
43
+ - **`affected(obj, callback)`**
44
+ Subscribes to changes in an observable object, `Set`, or `Map`.
45
+ - Supports `[obj, key]` to subscribe to a specific property.
46
+ - Returns an unsubscribe function.
47
+
48
+ - **`ref(initial)`**
49
+ Creates an observable reference with a `value` property.
50
+
51
+ - **`computed(src, cb, behavior, prop)`**
52
+ Creates a computed reactive value from a source.
53
+ - Computes its value using a callback function.
54
+ - Automatically updates when dependencies change.
55
+
56
+ - **`conditional(cond, ifTrue, ifFalse)`**
57
+ Reactive value that switches between `ifTrue` and `ifFalse` based on `cond.value`.
58
+
59
+ ### Install
60
+
61
+ ```bash
62
+ npm i @fest-lib/object.ts
63
+ ```
64
+
65
+ ### Importing
66
+
67
+ ```ts
68
+ import {
69
+ // Core reactivity
70
+ observe,
71
+ affected,
72
+ makeArrayObservable,
73
+ isObservable,
74
+ recoverReactive,
75
+
76
+ // Primitive refs
77
+ ref,
78
+ numberRef,
79
+ stringRef,
80
+ booleanRef,
81
+ autoRef,
82
+ promised,
83
+
84
+ // Computed and derived values
85
+ computed,
86
+ derivate,
87
+ conditional,
88
+ remap,
89
+ unified,
90
+
91
+ // Binding and assignment
92
+ bindBy,
93
+ assign,
94
+ link,
95
+
96
+ // Collection utilities
97
+ observableBySet,
98
+ observableByMap,
99
+ iterated,
100
+
101
+ // Subscription management
102
+ unaffected,
103
+ triggerWithDelay,
104
+ delayedBehavior,
105
+ delayedOrInstantBehavior,
106
+
107
+ // Utilities
108
+ safe,
109
+ deref,
110
+ unwrap,
111
+ propRef,
112
+
113
+ // Legacy (deprecated)
114
+ createReactive,
115
+ createReactiveMap,
116
+ createReactiveSet
117
+ } from "@fest-lib/object.ts";
118
+ ```
119
+
120
+ ### Quick start
121
+
122
+ ```ts
123
+ const state = observe({ count: 0, user: { name: "Ada" } });
124
+
125
+ const stop = affected(state, (value, prop) => {
126
+ console.log("changed:", prop, value[prop as keyof typeof value]);
127
+ });
128
+
129
+ state.count = 1;
130
+ stop?.();
131
+ ```
132
+
133
+ ### Primitive refs
134
+
135
+ ```ts
136
+ const n = numberRef(0);
137
+ const s = stringRef("hello");
138
+ const b = booleanRef(false);
139
+
140
+ n.value++; // 1
141
+ s.value = s + "!"; // "hello!"
142
+ b.value = 1; // true (truthy coercion)
143
+ ```
144
+
145
+ #### Auto ref and promised
146
+
147
+ ```ts
148
+ const r1 = autoRef(true); // booleanRef
149
+ const r2 = autoRef(42); // numberRef
150
+ const r3 = autoRef("hi"); // stringRef
151
+ const r4 = ref<any>({ a: 1 });
152
+
153
+ const later = promised(fetch("/api").then(r => r.status));
154
+ subscribe(later, () => console.log("ready:", later.value));
155
+ ```
156
+
157
+ ### Observing collections and properties
158
+
159
+ ```ts
160
+ const list = observe([1, 2, 3]);
161
+ const bag = observe(new Set(["a", "b"]));
162
+ const map = observe(new Map([["x", 1]]));
163
+
164
+ const unAll = affected(list, (v, prop) => console.log("list changed", prop));
165
+ const unBag = affected(bag, (v, prop) => console.log("set changed", prop));
166
+ const unMap = affected(map, (v, prop) => console.log("map changed", prop));
167
+
168
+ const person = observe({ name: "Ada", age: 36 });
169
+ const unName = affected([person, "name"], (v) => console.log("name:", v));
170
+
171
+ person.name = "Grace";
172
+ unAll?.(); unBag?.(); unMap?.(); unName?.();
173
+ ```
174
+
175
+ ### Deriving and binding
176
+
177
+ ```ts
178
+ const source = observe({ x: 1, y: 2 });
179
+
180
+ // Read-only derivative
181
+ const sum = derivate(source, s => ({ sum: s.x + s.y }));
182
+ affected(sum, () => console.log("sum:", sum.sum));
183
+
184
+ // Two-way bind by shape
185
+ const target: any = { x: 0, y: 0 };
186
+ bindBy(target, source);
187
+
188
+ source.x = 3; // target.x becomes 3
189
+ ```
190
+
191
+ ### Safe serialization
192
+
193
+ ```ts
194
+ const complex = observe({ d: new Date(), w: new WeakRef({ a: 1 }) });
195
+ JSON.stringify(safe(complex));
196
+ ```
197
+
198
+ ### Computed values
199
+
200
+ ```ts
201
+ const state = observe({ a: 1, b: 2 });
202
+ const sum = computed(state, s => s.a + s.b);
203
+
204
+ affected(sum, () => console.log("sum changed:", sum.value));
205
+ state.a = 3; // triggers: sum changed: 5
206
+ ```
207
+
208
+ ### Conditional reactivity
209
+
210
+ ```ts
211
+ const condition = booleanRef(true);
212
+ const result = conditional(condition, "yes", "no");
213
+
214
+ affected(result, () => console.log("result:", result.value));
215
+ condition.value = false; // triggers: result: no
216
+ ```
217
+
218
+ ### Property references
219
+
220
+ ```ts
221
+ const obj = observe({ nested: { value: 42 } });
222
+ const propRef = propRef(obj, "nested.value");
223
+
224
+ affected(propRef, () => console.log("nested value:", propRef.value));
225
+ obj.nested.value = 100; // triggers: nested value: 100
226
+ ```
227
+
228
+ ### Collection observables
229
+
230
+ ```ts
231
+ const set = observe(new Set([1, 2, 3]));
232
+ const arrayFromSet = observableBySet(set);
233
+
234
+ affected(arrayFromSet, () => console.log("set as array:", arrayFromSet));
235
+ set.add(4); // triggers: set as array: [1, 2, 3, 4]
236
+ ```
237
+
238
+ ### Notes
239
+
240
+ - Subscriptions fire only on actual changes.
241
+ - `observe` adapts `Set`/`Map` to emit iteration changes.
242
+ - To stop listening, keep the disposer returned by `affected` and call it.
243
+
244
+ ## API Reference
245
+
246
+ ### Core Reactivity
247
+
248
+ #### `observe<T>(target: T): observeValid<T>`
249
+
250
+ Creates a reactive proxy from an object, array, Set, or Map. Changes to the reactive object will trigger subscriptions.
251
+
252
+ ```ts
253
+ const obj = observe({ count: 0 });
254
+ const arr = observe([1, 2, 3]);
255
+ const set = observe(new Set([1, 2]));
256
+ ```
257
+
258
+ #### `affected(obj, callback): UnsubscribeFn`
259
+
260
+ Subscribes to changes on a reactive object. Returns an unsubscribe function.
261
+
262
+ ```ts
263
+ const state = observe({ count: 0 });
264
+ const unsubscribe = affected(state, (value, prop, old) => {
265
+ console.log(`${prop} changed from ${old} to ${value[prop]}`);
266
+ });
267
+ ```
268
+
269
+ #### `isObservable(obj): boolean`
270
+
271
+ Checks if an object is already reactive.
272
+
273
+ #### `recoverReactive(obj): observeValid | null`
274
+
275
+ Attempts to recover the reactive version of an object.
276
+
277
+ ### Reactive References
278
+
279
+ #### `ref<T>(initial: T): Ref<T>`
280
+
281
+ Creates a reactive reference with a `.value` property.
282
+
283
+ #### `numberRef(initial?: number): NumberRef`
284
+
285
+ Creates a reactive number reference with type coercion.
286
+
287
+ #### `stringRef(initial?: string): StringRef`
288
+
289
+ Creates a reactive string reference with type coercion.
290
+
291
+ #### `booleanRef(initial?: boolean): BooleanRef`
292
+
293
+ Creates a reactive boolean reference with truthy coercion.
294
+
295
+ #### `autoRef(initial: any): Ref`
296
+
297
+ Automatically creates the appropriate ref type based on the initial value.
298
+
299
+ #### `promised<T>(promise: Promise<T>): PromisedRef<T>`
300
+
301
+ Creates a reactive reference from a Promise.
302
+
303
+ ### Computed Values
304
+
305
+ #### `computed<T>(src, cb, behavior?, prop?): ComputedRef<T>`
306
+
307
+ Creates a computed reactive value that updates when its dependencies change.
308
+
309
+ ```ts
310
+ const state = observe({ a: 1, b: 2 });
311
+ const sum = computed(state, s => s.a + s.b);
312
+ ```
313
+
314
+ #### `derivate<T>(from, reactFn, watch?): observeValid`
315
+
316
+ Creates a derived reactive object from a source.
317
+
318
+ #### `conditional<T>(cond, ifTrue, ifFalse): ConditionalRef<T>`
319
+
320
+ Creates a reactive value that switches between two values based on a condition.
321
+
322
+ ### Binding & Assignment
323
+
324
+ #### `bindBy(target, reactive, watch?)`
325
+
326
+ Two-way binds a target object to a reactive source.
327
+
328
+ #### `assign<T>(a, b, prop?): UnsubscribeFn`
329
+
330
+ Assigns reactive values between objects with automatic synchronization.
331
+
332
+ #### `link<T>(a, b, prop?): UnsubscribeFn`
333
+
334
+ Creates a bidirectional link between two reactive values.
335
+
336
+ ### Collection Utilities
337
+
338
+ #### `observableBySet<T>(set: Set<T>): T[]`
339
+
340
+ Converts a reactive Set to a reactive array.
341
+
342
+ #### `observableByMap<K, V>(map: Map<K, V>): [K, V][]`
343
+
344
+ Converts a reactive Map to a reactive array of key-value pairs.
345
+
346
+ #### `iterated<T>(target, cb, ctx?): UnsubscribeFn`
347
+
348
+ Subscribes to iteration changes on collections.
349
+
350
+ #### `makeArrayObservable(target): observeValid`
351
+
352
+ Makes arrays observable.
353
+
354
+ ### Utilities
355
+
356
+ #### `safe(obj): any`
357
+
358
+ Prepares an object for JSON serialization by handling circular references and WeakRefs.
359
+
360
+ #### `deref(obj): any`
361
+
362
+ Dereferences WeakRefs and unwraps reactive objects.
363
+
364
+ #### `unwrap(obj): any`
365
+
366
+ Unwraps reactive objects to their original form.
367
+
368
+ #### `propRef<T>(src, prop, initial?, behavior?): Ref<T>`
369
+
370
+ Creates a reactive reference to a specific property.
371
+
372
+ ### Subscription Management
373
+
374
+ #### `unaffected<T>(target, cb?, ctx?): Promise<T>`
375
+
376
+ Removes subscriptions from an object.
377
+
378
+ #### `triggerWithDelay(ref, cb, delay?): Timeout`
379
+
380
+ Triggers a callback after a delay if the ref value is truthy.
381
+
382
+ #### `delayedBehavior(delay?): Function`
383
+
384
+ Creates a behavior function that delays execution.
385
+
386
+ #### `delayedOrInstantBehavior(delay?): Function`
387
+
388
+ Creates a behavior that executes immediately or after delay.
389
+
390
+ ### Legacy (Deprecated)
391
+
392
+ #### `createReactive(target, stateName?)`
393
+
394
+ Legacy function for creating reactive objects.
395
+
396
+ #### `createReactiveMap<K, V>(map?): Map<K, V>`
397
+
398
+ Legacy function for creating reactive Maps.
399
+
400
+ #### `createReactiveSet<V>(set?): Set<V>`
401
+
402
+ Legacy function for creating reactive Sets.
403
+
404
+ ***
405
+
406
+ ## Modules
407
+
408
+ - [core/Assigned](docs/core/Assigned/README.md) - Assignment and binding utilities
409
+ - [core/Legacy](docs/core/Legacy/README.md) - Legacy compatibility functions
410
+ - [core/Mainline](docs/core/Mainline/README.md) - Core subscription and reactivity system
411
+ - [core/Primitives](docs/core/Primitives/README.md) - Primitive reactive references
412
+ - [core/Specific](docs/core/Specific/README.md) - Specific object type handlers
413
+ - [core/Subscript](docs/core/Subscript/README.md) - Subscription registry system
414
+ - [index](docs/index/README.md) - Main exports
415
+ - [wrap/AssignObject](docs/wrap/AssignObject/README.md) - Object assignment proxy
416
+ - [wrap/Symbol](docs/wrap/Symbol/README.md) - Internal symbols and triggers
417
+ - [wrap/Utils](docs/wrap/Utils/README.md) - Utility functions and types
418
+
419
+ ---
420
+
421
+ ## License
422
+
423
+ This project is licensed under the [MIT License](LICENSE).