adaptive-extender 0.11.1 → 0.11.2

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 (3) hide show
  1. package/CHANGELOG.md +20 -10
  2. package/README.md +37 -32
  3. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,13 +1,23 @@
1
- ## 0.11.1 (21.06.2026)
2
- - Added `Array.Of(type)` portable adapter for typed arrays, alongside the existing `Array.import`/`Array.export`.
3
- - Added `Set.Of(type)` portable adapter for typed sets.
4
- - Added `Map.AsRecord(type)` and `Map.AsTuples(typeKey, typeValue)` portable adapters (moved from a separate module into [map](./src/core/map.ts)).
5
- - Added `Date.AsTimestamp` and `Date.AsUnixSeconds` portable adapters converting `Date` to millisecond and Unix-second numbers respectively.
6
- - Added `Number.prototype.snap(step)` — snaps a number to the nearest multiple of the given step.
7
- - **Breaking:** Removed `Reflect.mapNull`, `Reflect.mapUndefined`, and `Reflect.mapNullable`. Use `Nullable.map`, `Optional.map` from the portable module instead.
8
- - **Breaking:** Renamed `Archive`/`ArchiveManager`/`ArchiveRepository` to `Cell`/`PortableCell`/`BufferedCell`. Construction is now done via `Storage` factory methods (`localStorage.openCell`, `localStorage.openPortableCell`, `localStorage.openBufferedCell`) — the storage backend is no longer hardcoded to `localStorage`.
9
- - **Breaking:** `@Field` decorator no longer accepts a positional string as the second argument. Use `{ name: "..." }` options object: `@Field(String, { name: "fieldName" })`.
10
- - `PortableCell.save()` returns `Promise<boolean>` resolves `true` when persisted, `false` if cancelled (superseded or aborted); rejects only on serialization failure.
1
+ ## 0.11.2 (21.06.2026)
2
+ - Added `Number.prototype.snap(step)` snaps a number to the nearest multiple of `step`.
3
+ - Added `Array.Of(type)` portable adapter for typed arrays, as a `PortableConstructor` wrapper usable with `@Field`.
4
+ - Added `Set.Of(type)` portable adapter for typed sets, serialized as arrays.
5
+ - Added `Map.AsRecord(type)` portable adapter converts `Map<string, T>` to and from a plain `Record<string, S>`.
6
+ - Added `Map.AsTuples(typeKey, typeValue)` portable adapter converts `Map<K, V>` to and from `[K, V][]` tuple arrays.
7
+ - Added `Date.AsTimestamp` portable adapter converts between `Date` instances and millisecond timestamps.
8
+ - Added `Date.AsUnixSeconds` portable adapter converts between `Date` instances and Unix-second integers.
9
+ - Added `Optional.Of(type)` and `Optional.map(value, fn)` static methods on the `Optional` class.
10
+ - Added `Nullable.Of(type)` and `Nullable.map(value, fn)` static methods on the `Nullable` class.
11
+ - Added `Enum.Of(reference)` static method on the new `Enum` class.
12
+ - Added `Storage.openCell(key, initial)`, `Storage.openPortableCell(key, model, instance)`, and `Storage.openBufferedCell(key, model, instance)` factory methods on the `Storage` prototype.
13
+ - `BufferedCell.save()` returns `Promise<boolean>` — resolves `true` when persisted, `false` if cancelled (superseded or aborted); rejects only on serialization failure.
14
+ - **Breaking:** Renamed `Archive` → `Cell`, `ArchiveManager` → `PortableCell`, `ArchiveRepository` → `BufferedCell`. All three constructors now require an explicit `storage` as their first argument (e.g. `localStorage.openBufferedCell(key, model, instance)`) — the backend is no longer hardcoded to `localStorage`.
15
+ - **Breaking:** `Optional(type)` and `Nullable(type)` call syntax removed — use `Optional.Of(type)` and `Nullable.Of(type)` instead.
16
+ - **Breaking:** `ArrayOf(type)`, `SetOf(type)`, `RecordOf(type)`, `MapOf(K, V)` adapter functions removed — use `Array.Of(type)`, `Set.Of(type)`, `Map.AsRecord(type)`, `Map.AsTuples(K, V)` instead.
17
+ - **Breaking:** `EnumAs(reference)` function removed — use `Enum.Of(reference)` instead.
18
+ - **Breaking:** `Timestamp` and `UnixSeconds` portable constants removed — use `Date.AsTimestamp` and `Date.AsUnixSeconds` instead.
19
+ - **Breaking:** Removed `Reflect.mapNull`, `Reflect.mapUndefined`, and `Reflect.mapNullable` — use `Nullable.map(value, fn)` and `Optional.map(value, fn)` instead.
20
+ - **Breaking:** `@Field(type, "name")` positional string shorthand removed — use `@Field(type, { name: "name" })` options object instead.
11
21
 
12
22
  ## 0.10.5 (13.06.2026)
13
23
  - Bugfix at [portable](./src/core/portable.ts).
package/README.md CHANGED
@@ -47,6 +47,9 @@ const pixelX = angle.lerp(0, 360, 0, canvasWidth);
47
47
  // True mathematical modulo — works correctly with negative numbers
48
48
  const wrappedIndex = (-1).mod(items.length); // → items.length - 1
49
49
 
50
+ // Snap to a grid step
51
+ const snapped = (3.7).snap(0.5); // → 4
52
+
50
53
  // Chainable fallback for invalid values
51
54
  const ratio = (numerator / denominator).insteadNaN(0).insteadInfinity(1);
52
55
  ```
@@ -268,7 +271,7 @@ class AppConfig extends Model {
268
271
  @Field(Number)
269
272
  DB_PORT: number = 5432;
270
273
 
271
- @Field(Optional(String))
274
+ @Field(Optional.Of(String))
272
275
  LOG_LEVEL?: string;
273
276
  }
274
277
 
@@ -284,7 +287,7 @@ Binds classes to their schema via decorators. Importing from JSON validates type
284
287
  ### Basic Usage
285
288
 
286
289
  ```typescript
287
- import { Model, Field, ArrayOf, Optional, Nullable } from "adaptive-extender/core";
290
+ import { Model, Field, Optional, Nullable } from "adaptive-extender/core";
288
291
 
289
292
  class Tag extends Model {
290
293
  @Field(String)
@@ -298,13 +301,13 @@ class Article extends Model {
298
301
  @Field(Number)
299
302
  views: number = 0;
300
303
 
301
- @Field(ArrayOf(Tag))
304
+ @Field(Array.Of(Tag))
302
305
  tags: Tag[] = [];
303
306
 
304
- @Field(Optional(String))
307
+ @Field(Optional.Of(String))
305
308
  subtitle?: string;
306
309
 
307
- @Field(Nullable(String))
310
+ @Field(Nullable.Of(String))
308
311
  draft: string | null = null;
309
312
  }
310
313
 
@@ -343,16 +346,18 @@ const animal = Animal.import(json, "api.animal");
343
346
 
344
347
  ### Adapters
345
348
 
346
- | Adapter | Type |
347
- | :----------------- | :------------------------------------- |
348
- | `ArrayOf(T)` | `T[]` |
349
- | `SetOf(T)` | `Set<T>` ↔ `T[]` |
350
- | `RecordOf(T)` | `Map<string, T>` ↔ `Record<string, T>` |
351
- | `MapOf(K, V)` | `Map<K, V>` ↔ `[K, V][]` |
352
- | `Optional(T)` | `T \| undefined` |
353
- | `Nullable(T)` | `T \| null` |
354
- | `Deferred(_ => T)` | Circular references |
355
- | `EnumAs(E)` | TypeScript `enum` or const-object enum |
349
+ | Adapter | Type |
350
+ | :------------------- | :------------------------------------- |
351
+ | `Array.Of(T)` | `T[]` |
352
+ | `Set.Of(T)` | `Set<T>` ↔ `T[]` |
353
+ | `Map.AsRecord(T)` | `Map<string, T>` ↔ `Record<string, T>` |
354
+ | `Map.AsTuples(K, V)` | `Map<K, V>` ↔ `[K, V][]` |
355
+ | `Optional.Of(T)` | `T \| undefined` |
356
+ | `Nullable.Of(T)` | `T \| null` |
357
+ | `Deferred(_ => T)` | Circular references |
358
+ | `Enum.Of(E)` | TypeScript `enum` or const-object enum |
359
+ | `Date.AsTimestamp` | `Date` ↔ milliseconds (`number`) |
360
+ | `Date.AsUnixSeconds` | `Date` ↔ Unix seconds (`number`) |
356
361
 
357
362
  ## Web
358
363
 
@@ -392,12 +397,12 @@ const fixedEngine = new StaticEngine({ launch: true });
392
397
  fixedEngine.limit = 30;
393
398
  ```
394
399
 
395
- ### Archive (localStorage)
400
+ ### Storage (localStorage)
396
401
 
397
- Type-safe localStorage with buffered access and auto-save.
402
+ Type-safe storage with buffered access and auto-save. Use the factory methods on any `Storage` instance (`localStorage`, `sessionStorage`, or custom) to create typed cells.
398
403
 
399
404
  ```typescript
400
- import { ArchiveRepository, Model, Field } from "adaptive-extender/web";
405
+ import { Model, Field } from "adaptive-extender/web";
401
406
 
402
407
  class Settings extends Model {
403
408
  @Field(Boolean)
@@ -407,16 +412,25 @@ class Settings extends Model {
407
412
  volume: number = 1;
408
413
  }
409
414
 
410
- const repository = new ArchiveRepository("settings", Settings, new Settings());
415
+ // BufferedCell buffered read/write with debounced auto-save
416
+ const cell = localStorage.openBufferedCell("settings", Settings, new Settings());
411
417
 
412
- const settings = repository.content;
418
+ const settings = cell.content;
413
419
  settings.volume = 0.5;
414
420
 
415
421
  // save() resolves true when persisted, false if cancelled (superseded or aborted), rejects only on serialization failure
416
- const saved = await repository.save(); // save immediately
417
- await repository.save(3000); // debounced — save after 3 seconds
422
+ const saved = await cell.save(); // save immediately
423
+ await cell.save(3000); // debounced — save after 3 seconds
418
424
  // A pending save resolves false when superseded by a new call or cancelled by abort()
419
- repository.reset(); // abort pending save and revert to initial state
425
+ cell.reset(); // abort pending save and revert to initial state
426
+
427
+ // PortableCell — direct typed read/write without buffering
428
+ const typed = localStorage.openPortableCell("config", Settings, new Settings());
429
+ typed.content = settings;
430
+
431
+ // Cell — raw JSON storage
432
+ const raw = localStorage.openCell("flags", { debug: false });
433
+ raw.data = { debug: true };
420
434
  ```
421
435
 
422
436
  ### Promise Utilities
@@ -431,15 +445,6 @@ const result = await Promise.withSignal((signal, resolve, reject) => {
431
445
  });
432
446
  ```
433
447
 
434
- ## Reflect Utilities
435
-
436
- ```typescript
437
- // Apply a function only if the value is not null / undefined
438
- const upper = Reflect.mapNull(maybeNull, text => text.toUpperCase());
439
- const trimmed = Reflect.mapUndefined(maybeUndefined, text => text.trim());
440
- const parsed = Reflect.mapNullable(maybeNullable, text => Number.parseInt(text));
441
- ```
442
-
443
448
  ## License
444
449
 
445
450
  Apache-2.0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "adaptive-extender",
3
- "version": "0.11.1",
3
+ "version": "0.11.2",
4
4
  "description": "Adaptive library for JS/TS development environments",
5
5
  "type": "module",
6
6
  "main": "./dist/core/index.js",