@the-w1zard/dx 1.0.8 → 1.0.9

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/README.md CHANGED
@@ -2,10 +2,18 @@
2
2
  <div align="left" style="position: relative;">
3
3
  <img src="./icons/gandalf.png" align="right" width="30%" style="margin: -20px 0 0 20px;">
4
4
 
5
- <h1>DX: <span style="font-size:18px;" >The Wizard's Arsenal</span></h1>
5
+ <h3 style="font-size:26px;">DX: <span style="font-size:18px;" >The Wizard's Arsenal</span></h3>
6
6
 
7
7
  <p align="left"><em>The most opinionated platform... ever.</em></p>
8
8
  <p align="left"><em>Trust me... I'm a fucking wizard... 🧙</em></p>
9
+ <p align="left">Platforms stats:</p>
10
+ <p align="left">
11
+ <img src="https://img.shields.io/badge/LINES OF CODE- 10,300,000-95ED27?style=flat">
12
+ <img src="https://img.shields.io/badge/FEATURES- UNKNOWN-95ED27?style=flat">
13
+ <img src="https://img.shields.io/badge/REACTS RULES ON HOOKS- 0-95ED27?style=flat">
14
+ <img src="https://img.shields.io/badge/DISRUPTORS- 18+-95ED27?style=flat">
15
+ <img src="https://img.shields.io/badge/MESSAGE QUEUES- 5-95ED27?style=flat">
16
+ </p>
9
17
  <p align="left">VSCode ext:</p>
10
18
  <p align="left">
11
19
  <img src="https://img.shields.io/badge/THEMES- 251-95ED27?style=flat">
@@ -18,17 +26,17 @@
18
26
  <p align="left">Small but powerful repos worth checking out:</p>
19
27
  <p align="left">
20
28
 
21
- <a href="https://github.com/the-w1zard/app_store"><img src="https://img.shields.io/badge/Store / Maelstrom-000000.svg?style=flat&logo=JetBrains&logoColor=white" alt="JetBrains"></a>
22
- <a href="https://github.com/the-w1zard/dx"><img src="https://img.shields.io/badge/UX /DX-34A853.svg?style=flat&logo=Android&logoColor=white" alt="Android"></a>
23
- <a href="https://github.com/the-w1zard/temporal_shift"><img src="https://img.shields.io/badge/Temporal Shift-77AA99.svg?style=flat&logo=Org&logoColor=white" alt="Org"></a>
24
- <a href="https://github.com/the-w1zard/the_cloud"><img src="https://img.shields.io/badge/The Cloud-02303A.svg?style=flat&logo=Gradle&logoColor=white" alt="Gradle"></a>
25
- <a href="https://github.com/the-w1zard/signals"><img src="https://img.shields.io/badge/Signals-02303A.svg?style=flat&logo=Gradle&logoColor=white" alt="Gradle"></a>
26
- <img src="https://img.shields.io/badge/Sometimes, my genius... It generates gravity.-4285F4.svg?style=flat&logo=🧙&logoColor=white" alt="Google">
27
- <a href="https://github.com/the-w1zard"><img src="https://img.shields.io/badge/Coming Soon: The Wizard Platform-7F52FF.svg?style=flat&logo=Kotlin&logoColor=white" alt="Kotlin"></a>
28
- <a href="https://github.com/the-w1zard"><img src="https://img.shields.io/badge/Coming Soon: Hadron Particle Disruptor-%23ED8B00.svg?style=flat&logo=openjdk&logoColor=white" alt="java"></a>
29
+ - [![🧙 Alias Types](https://img.shields.io/badge/Alias%20Types-000000.svg?style=flat&logo=typescript&logoColor=white)](https://github.com/the-w1zard/alias_types) <a href="https://www.npmjs.com/package/@the-w1zard/alias_types"><img src="./icons/npm.png" alt="alias_types" width="20" height="20"></a>
30
+ - [![🧙 The Cloud](https://img.shields.io/badge/%F0%9F%A7%99%20App%20Store-000000.svg?style=flat)](https://github.com/the-w1zard/app_store) <a href="https://www.npmjs.com/package/@the-w1zard/store"><img src="./icons/npm.png" alt="app_store" width="20" height="20"></a>
31
+ - [![🧙 The Cloud](https://img.shields.io/badge/%F0%9F%A7%99%20DX-95ED27.svg?style=flat)](https://github.com/the-w1zard/dx) <a href="https://www.npmjs.com/package/@the-w1zard/dx"><img src="./icons/npm.png" alt="dx" width="20" height="20"></a>
32
+ - [![🧙 The Cloud](https://img.shields.io/badge/%F0%9F%A7%99%20Temporal%20Shift-77AA99.svg?style=flat)](https://github.com/the-w1zard/temporal_shift) <a href="https://www.npmjs.com/package/@the-w1zard/temporal_shift"><img src="./icons/npm.png" alt="temporal_shift" width="20" height="20"></a>
33
+ - [![🧙 The Cloud](https://img.shields.io/badge/%F0%9F%A7%99%20The%20Cloud-02303A.svg?style=flat)](https://github.com/the-w1zard/the_cloud) <a href="https://www.npmjs.com/package/@the-w1zard/the-cloud"><img src="./icons/npm.png" alt="app_store" width="20" height="20"></a>
34
+ - [![🧙 SINGULARITY](https://img.shields.io/badge/%F0%9F%A7%99%20SINGULARITY-02303A.svg?style=flat)](https://github.com/the-w1zard)
35
+ - [![🧙 Sometimes,%20my%20genius...%20It%20generates%20gravity.](https://img.shields.io/badge/%F0%9F%A7%99%20Sometimes,%20my%20genius...%20It%20generates%20gravity.-4285F4.svg?style=flat)](https://github.com/the-w1zard)
36
+ - [![🧙 The Wizard](https://img.shields.io/badge/%F0%9F%A7%99%20Coming%20Soon:%20The%20Wizard%20Ed.-7F52FF.svg?style=flat)](https://github.com/the-w1zard)
37
+ - [![🧙 Hadron Particle Disruptor](https://img.shields.io/badge/%F0%9F%A7%99%20Coming%20Soon:%20Hadron%20Particle%20Disruptor-23ED8B00.svg?style=flat)](https://github.com/the-w1zard)
29
38
  </p>
30
39
  <p align="left">The goal? To remove all friction, from everything.</p>
31
-
32
40
  </div>
33
41
  <br clear="right">
34
42
 
@@ -53,21 +61,26 @@ The package extends native classes and exposes their implementations through `gl
53
61
 
54
62
  ## Table of Contents
55
63
 
56
- - [A2 — Array](#a2--array)
57
- - [D2 — Date](#d2--date)
58
- - [ER2 — Error](#er2--error)
59
- - [I2 — Iterator](#i2--iterator)
60
- - [M2 — Map](#m2--map)
61
- - [N2 — Number](#n2--number)
62
- - [O2 — Object](#o2--object)
63
- - [P2 — Promise](#p2--promise)
64
- - [USP2 — URLSearchParams](#usp2--urlsearchparams)
65
- - [U82 — Array](#u82--array)
66
- - [S2 — String](#s2--string)
67
- - [WS2 — WeakSet](#ws2--weakset)
68
- - [WM2 — WeakMap](#wm2--weakmap)
69
- - [O2 — Object](#o2--object)
70
- - [SET2 — Set](#set2--set)
64
+ <ul style="list-style: none; padding-left: 0;">
65
+ <li><a href="#a2--array">A2 — Array</a></li>
66
+ <li><a href="#b2--byte-bool">B2 — Byte Boolean</a></li>
67
+ <li><a href="#d2--date">D2 — Date</a></li>
68
+ <li><a href="#er2--error">ER2 — Error</a></li>
69
+ <li><a href="#i2--iterator">I2 — Iterator</a></li>
70
+ <li><a href="#m2--map">M2 — Map</a></li>
71
+ <li><a href="#m2b--map-binary">M2B — Map Binary</a></li>
72
+ <li><a href="#n2--number">N2 — Number</a></li>
73
+ <li><a href="#o2--object">O2 — Object</a></li>
74
+ <li><a href="#p2--promise">P2 — Promise</a></li>
75
+ <li><a href="#usp2--urlsearchparams">USP2 — URLSearchParams</a></li>
76
+ <li><a href="#u82--array">U82 — Uint8Array</a></li>
77
+ <li><a href="#s2--string">S2 — String</a></li>
78
+ <li><a href="#ws2--weakset">WS2 — WeakSet</a></li>
79
+ <li><a href="#wm2--weakmap">WM2 — WeakMap</a></li>
80
+ <li><a href="#o2--object">O2 — Object</a></li>
81
+ <li><a href="#set2--set">SET2 — Set</a></li>
82
+ <li><a href="#set2b--set-binary">SET2B — Set Binary</a></li>
83
+ </ul>
71
84
 
72
85
  > [!IMPORTANT] UPDATE!!@!
73
86
  >
@@ -128,6 +141,7 @@ The global declarations provide TypeScript access to these APIs. `MaybePromise`
128
141
 
129
142
  ## Quick Reference
130
143
 
144
+
131
145
  ## `A2` — Array
132
146
 
133
147
  `A2I` extends `Array` and adds collection helpers. Methods returning arrays generally return `A2I` instances.
@@ -164,57 +178,111 @@ The global declarations provide TypeScript access to these APIs. `MaybePromise`
164
178
  Static helpers include `A2I.from()` and `A2I.of()`.
165
179
 
166
180
 
181
+ ## `B2` — Byte Bool
182
+
183
+ `B2I` replaces boolean properties and boolean maps with a zero-allocation, PID-indexed `Uint8Array` lane. One byte per PID, no boxing, no `Map`, no per-entry allocation — `set`, `get`, and `toggle` are O(1) array stores, and `clear` is a single `fill(0)`.
184
+
185
+ | Method | Description |
186
+ |---|---|
187
+ | `set(pid, value)` | Set the boolean flag for a PID |
188
+ | `true(pid, value)` | Set the flag to `1` (`value` is accepted for call-site symmetry and ignored) |
189
+ | `false(pid, value)` | Set the flag to `0` (`value` is accepted for call-site symmetry and ignored) |
190
+ | `get(pid)` | Return `true` if the PID's flag is `1`, else `false` |
191
+ | `toggle(pid)` | Flip the PID's flag and return the new state |
192
+ | `clear()` | Zero every flag in place; no reallocation |
193
+ | `flags` | The backing `Uint8Array`, indexed by PID |
194
+
167
195
  ## `D2` — Date
168
196
 
197
+ `D2` extends `Date` and keeps the standard `Date` API, adding immutable date arithmetic, calendar helpers, human-readable diffs, custom formatting, and locale-aware parsing. Every method returns a new `D2I`; the receiver is never mutated.
198
+
199
+ Registered as a codec (`DATE_TAG = 0x4432`, `"D2"`): `enc` writes the epoch-ms as an `i64`, `dec` revives it as a `D2I`.
200
+
201
+ | Method | Description |
202
+ |---|---|
203
+ | `set(f)` | Return a new date with the given `{ year, month, day, hour, minute, second, ms }` fields applied; unset fields are preserved, `day` is clamped to the target month |
204
+ | `withDate(year, month, day)` | Replace the calendar date, keep the time |
205
+ | `sameTimeOn(other)` | Keep this date's time, adopt `other`'s calendar date |
206
+ | `at(hour, minute?, second?, ms?)` | Return a new date at the given time on this date |
207
+ | `atNoon()` / `midnight()` | `at(12)` / `startOfDay()` |
208
+ | `toInputDate()` / `toInputTime()` / `toInputDateTime()` / `toInputTimeWithSeconds()` | `YYYY-MM-DD`, `HH:mm`, `YYYY-MM-DDTHH:mm`, `HH:mm:ss` for form inputs |
209
+
210
+ ### Arithmetic
211
+
212
+ | Method | Description |
213
+ |---|---|
214
+ | `addMs` / `addSeconds` / `addMinutes` / `addHours` / `addDays` / `addWeeks` / `addMonths` / `addYears` | Return a new date shifted by the amount |
215
+ | `subDays` / `subWeeks` / `subMonths` / `subYears` | Negative-shift shorthand |
216
+ | `addBusinessDays(n)` / `nextBusinessDay()` / `prevBusinessDay()` | Shift by weekdays, skipping weekends |
217
+ | `next(unit)` / `prev(unit)` | Next/previous `day`, `week`, `month`, `quarter`, `year`, or weekday name (`"friday"`) |
218
+ | `nextWeek` / `prevWeek` / `nextMonth` / `prevMonth` / `nextQuarter` / `prevQuarter` / `nextYear` / `prevYear` | Named shorthands |
219
+
220
+ ### Boundaries
221
+
222
+ | Method | Description |
223
+ |---|---|
224
+ | `startOfDay` / `endOfDay` | Local day boundaries |
225
+ | `startOfWeek(weekStartsOn?)` / `endOfWeek(weekStartsOn?)` | Week boundaries; `weekStartsOn` defaults to `0` (Sunday) |
226
+ | `startOfMonth` / `endOfMonth` | Month boundaries |
227
+ | `startOfQuarter` / `endOfQuarter` | Quarter boundaries |
228
+ | `startOfYear` / `endOfYear` | Year boundaries |
229
+
230
+ ### Fields and predicates
231
+
232
+ | Method | Description |
233
+ |---|---|
234
+ | `month()` | 1-based month |
235
+ | `dateOfWeek()` / `dayOfYear()` / `quarter()` | Calendar fields |
236
+ | `daysInMonth()` / `daysInYear()` / `isLeapYear()` | Calendar facts |
237
+ | `isWeekend()` / `isWeekday()` / `isBusinessDay()` | Day-type predicates |
238
+ | `isBefore` / `isAfter` / `isEqual` / `isBetween` / `isSameOrBefore` / `isSameOrAfter` | Instant comparison |
239
+ | `sameDay` / `sameMonth` / `sameYear` / `isSame(unit, other)` | Calendar comparison |
240
+ | `isToday` / `isTomorrow` / `isYesterday` | Relative-day predicates |
241
+ | `clamp(min, max)` | Clamp into a range |
242
+
243
+ ### Differences
244
+
245
+ | Method | Description |
246
+ |---|---|
247
+ | `diffMs` / `diffSeconds` / `diffMinutes` / `diffHours` / `diffDays` | Numeric difference from `other` |
248
+ | `calendarDays(other)` | Whole calendar days between the two dates |
249
+ | `businessDays(other)` | Weekdays between the two dates |
250
+ | `diffHuman(other?)` | Compact human diff, e.g. `"3d"` |
251
+ | `fromNow()` / `ago()` | Relative description, e.g. `"in 2 hours"`, `"3 minutes ago"` |
252
+ | `from(other)` | Relative description vs. `other` |
253
+ | `age(unit?)` | Elapsed years/months/days since this date |
254
+
255
+ ### Formatting and parsing
256
+
257
+ | Method | Description |
258
+ |---|---|
259
+ | `fmt(format)` | Token substitution: `YYYY`, `YY`, `MMMM`, `MMM`, `MM`, `M`, `DD`, `D`, `dddd`, `ddd`, `HH`, `H`, `hh`, `h`, `mm`, `m`, `ss`, `s`, `SSS`, `A`, `a` |
260
+ | `toLocalString(format?)` | `toLocaleString("en-US", format)`; `format` defaults to `FORMAT.full` |
261
+ | `D2.from(value)` | Parse from `Date`, number (epoch ms), ISO string, `YYYY-MM-DD`, `YYYY-MM-DD HH:mm`, array `[y,m,d,h?,min?,s?,ms?]`, or object (`{ date, time }` or `{ year, month, day, … }`) |
262
+ | `D2.parseDate("YYYY-MM-DD")` | Local midnight for that date |
263
+ | `D2.parseDateTime("YYYY-MM-DD HH:mm")` | Local date-time |
264
+ | `D2.fromParts(y, m, d, h?, min?, s?, ms?)` | Construct from calendar parts |
265
+
266
+ ### Statics
267
+
169
268
  | Method | Description |
170
269
  |---|---|
171
- | `clone()` / `isValid()` | Copy a date or check validity |
172
- | `month()` / `dateOfWeek()` | Get one-based month or weekday index |
173
- | `dayOfYear()` / `quarter()` | Get day of year or quarter |
174
- | `unix()` / `toUnix()` | Get Unix timestamp in seconds |
175
- | `toUnixMs()` | Get Unix timestamp in milliseconds |
176
- | `age(unit?)` | Get age in years, months, or days from this date to now |
177
- | `addMs()` / `addSeconds()` / `addMinutes()` / `addHours()` | Add time |
178
- | `addDays()` / `addWeeks()` / `addMonths()` / `addYears()` | Add calendar units |
179
- | `subDays()` / `subWeeks()` / `subMonths()` / `subYears()` | Subtract calendar units |
180
- | `startOfDay()` / `endOfDay()` | Day boundaries |
181
- | `startOfWeek(weekStartsOn?)` / `endOfWeek(weekStartsOn?)` | Week boundaries |
182
- | `startOfMonth()` / `endOfMonth()` | Month boundaries |
183
- | `startOfQuarter()` / `endOfQuarter()` | Quarter boundaries |
184
- | `startOfYear()` / `endOfYear()` | Year boundaries |
185
- | `daysInMonth()` / `daysInYear()` | Count days |
186
- | `isLeapYear()` | Check leap year |
187
- | `isWeekend()` / `isWeekday()` | Check day type |
188
- | `isBefore(date)` / `isAfter(date)` / `isEqual(date)` | Compare timestamps |
189
- | `isSameOrBefore(date)` / `isSameOrAfter(date)` | Compare timestamps, inclusive |
190
- | `isBetween(start, end)` | Check an inclusive date range |
191
- | `clamp(min, max)` | Constrain a date to a range |
192
- | `diffMs()` / `diffSeconds()` / `diffMinutes()` / `diffHours()` / `diffDays()` | Calculate signed time differences |
193
- | `sameDay()` / `sameMonth()` / `sameYear()` | Compare calendar components |
194
- | `isSame(unit, date)` | Compare by day, week, month, quarter, or year |
195
- | `isToday()` / `isTomorrow()` / `isYesterday()` | Check relative to the current date |
196
- | `ago()` / `fromNow()` | Relative-time label vs. now |
197
- | `from(other)` | Relative-time label vs. a given date |
198
- | `next(unit)` / `prev(unit)` | Jump to the next/previous weekday name or calendar unit |
199
- | `nextWeek()` / `prevWeek()` / `nextMonth()` / `prevMonth()` / `nextQuarter()` / `prevQuarter()` / `nextYear()` / `prevYear()` | Shortcut unit navigation |
200
- | `at(hour, minute?, second?, ms?)` | Set a specific time of day |
201
- | `atNoon()` / `midnight()` | Jump to noon or start of day |
202
- | `addBusinessDays(n)` / `nextBusinessDay()` / `prevBusinessDay()` | Business-day navigation |
203
- | `isBusinessDay()` | Check if this date is a weekday |
204
- | `calendarDays(other)` | Signed whole-day difference, ignoring time of day |
205
- | `businessDays(other)` | Count weekdays between this date and another |
206
- | `diffHuman(other?)` | Single-unit human-readable duration (e.g. `"3d"`) |
207
- | `fmt(format)` | Format using token strings (`YYYY`, `MMM`, `dddd`, etc.) |
208
- | `toLocalString(format?)` | Format via `Date.prototype.toLocaleString` |
209
- | `toInputDate()` / `toInputTime()` / `toInputDateTime()` / `toInputTimeWithSeconds()` | Format for HTML `<input>` fields |
210
- | `set(fields)` | Immutably update one or more date/time fields, preserving the rest |
211
- | `withDate(year, month, day)` | Shortcut for `set()` on the date portion |
212
- | `sameTimeOn(other)` | Keep this date's time, swap in another date's day |
213
- | `to(other)` | Build an `R2` range from this date to another |
214
- | `toD2()` | Return a cloned `D2` |
215
-
216
- Static helpers include `now()`, `fromUnix()`, `fromUnixMs()`, `fromParts()`, `today()`, `min()`, `max()`, `from(value)` (flexible ingestion from `Date`, epoch ms, ISO/local strings, arrays, or field objects), `parseDate(str)`, and `parseDateTime(str)`.
270
+ | `D2.now()` / `D2.today()` | Current instant / today's `startOfDay()` |
271
+ | `D2.fromUnix(s)` / `D2.fromUnixMs(ms)` | Construct from epoch seconds / milliseconds |
272
+ | `D2.min(...dates)` / `D2.max(...dates)` | Earliest / latest of the inputs |
217
273
 
274
+ ### Ranges
275
+
276
+ `R2I` is a half-open `[start, end)` interval.
277
+
278
+ | Method | Description |
279
+ |---|---|
280
+ | `contains(d)` | Whether `d` falls inside the range |
281
+ | `overlaps(other)` | Whether two ranges intersect |
282
+ | `durationMs()` / `days()` | Length in ms / whole days |
283
+ | `eachDay(fn)` | Iterate each calendar day in the range |
284
+ | `toArray()` | `A2I<D2>` of days |
285
+ | `R2(start, end)` | Build a range from any two `D2`-coercible values |
218
286
 
219
287
  ## `ER2` — Error
220
288
 
@@ -229,13 +297,13 @@ Static helpers include `now()`, `fromUnix()`, `fromUnixMs()`, `fromParts()`, `to
229
297
  | `ER2.wrap(value, message?)` | Wrap an error with a cause |
230
298
  | `ER2.aggregate(errors, message?)` | Create an `AggregateError` from multiple errors |
231
299
 
232
- `ER2I` accepts an optional message and standard `ErrorOptions`, including `cause`.
300
+ `ER2` accepts an optional message and standard `ErrorOptions`, including `cause`.
233
301
 
234
302
 
235
303
 
236
304
  ## `I2` — Iterator
237
305
 
238
- `I2I` wraps an iterable or iterator and provides lazy transformation pipelines.
306
+ `I2` wraps an iterable or iterator and provides lazy transformation pipelines.
239
307
 
240
308
  | Method | Description |
241
309
  |---|---|
@@ -270,13 +338,14 @@ Static helpers include `now()`, `fromUnix()`, `fromUnixMs()`, `fromParts()`, `to
270
338
 
271
339
  ## `M2` — Map
272
340
 
273
- `M2I` extends `Map` and retains the standard `Map` API, plus reactive subscriptions, derived values, and batching.
341
+ `M2` extends `Map` and retains the standard `Map` API, plus reactive subscriptions, derived values, batching, and a large set of convenience methods. Keys are arbitrary — any value `Map` accepts, `M2` accepts.
274
342
 
275
343
  | Method | Description |
276
344
  |---|---|
277
345
  | `g(key)` / `h(key)` / `d(key)` / `c()` | Aliases for `get`, `has`, `delete`, and `clear` |
278
346
  | `f` | Alias for `forEach` |
279
347
  | `s(value, key)` | Set a value; function arguments are evaluated as factories |
348
+ | `mutate(key, fn)` | Update an existing value in place using the current value |
280
349
  | `swap(value, key)` | Replace a value and return the previous value |
281
350
  | `take(key)` | Get and delete a value |
282
351
  | `peek(key)` | Return the value or `false` if absent |
@@ -288,7 +357,6 @@ Static helpers include `now()`, `fromUnix()`, `fromUnixMs()`, `fromParts()`, `to
288
357
  | `replace(value, key)` | Replace only when present |
289
358
  | `inc(key, by?)` | Increment a numeric entry |
290
359
  | `touch(key)` | Ensure a key exists |
291
- | `mutate(key, fn)` | Update an existing value in place using the current value |
292
360
  | `mapValues(fn)` / `mapKeys(fn)` | Transform values or keys into a new map |
293
361
  | `filterKV(pred)` / `filterKeys(pred)` | Filter in place |
294
362
  | `partition(pred)` | Split entries into matching and nonmatching maps |
@@ -321,6 +389,64 @@ Static helpers include `now()`, `fromUnix()`, `fromUnixMs()`, `fromParts()`, `to
321
389
  | `fromEntries(entries)` | Create a map from entries |
322
390
  | `from(map)` | Create a map from another map |
323
391
 
392
+
393
+ ## `M2B` — Map binary
394
+
395
+ `M2B` is the dense, PID-indexed backing store for `M2`. Where `M2` accepts arbitrary keys and stores values in a `Map`, `M2B` stores fixed-width values in a flat `Float64Array`, indexed by integer PID. `pidToSlot` / `slotToPid` give O(1) lookup in both directions, and iteration walks the dense slot range — no hashing, no per-entry allocation.
396
+
397
+ `stride` controls how many doubles each PID holds: `stride = 1` stores scalars (`number`), `stride > 1` stores fixed-length `Float64Array` views. `cap` is the maximum PID; values outside `[0, cap)` read as absent.
398
+
399
+ | Method | Description |
400
+ |---|---|
401
+ | `g(pid)` / `h(pid)` / `d(pid)` / `c()` | Aliases for `get`, `has`, `delete`, and `clear` |
402
+ | `f` | Alias for `forEach` |
403
+ | `s(value, pid)` | Set a value for a PID |
404
+ | `mutate(pid, fn)` | Update an existing value in place using the current value |
405
+ | `swap(value, pid)` | Replace a value and return the previous value |
406
+ | `take(pid)` | Get and delete a value |
407
+ | `peek(pid)` | Return the value or `false` if absent |
408
+ | `getOrI(value, pid)` | Get or insert a supplied value |
409
+ | `getOrM(make, pid)` | Get or lazily create a value |
410
+ | `update(pid, fn, initial?)` | Update using the current value, or an initial value if missing |
411
+ | `setIfAbsent(value, pid)` | Insert only when missing |
412
+ | `setIfPresent(value, pid)` | Set only when present |
413
+ | `replace(value, pid)` | Replace only when present |
414
+ | `inc(pid, by?)` | Increment a numeric entry |
415
+ | `touch(pid)` | Ensure a PID exists |
416
+ | `mapValues(fn)` / `mapKeys(fn)` | Transform values or PIDs into a new map |
417
+ | `filterKV(pred)` / `filterKeys(pred)` | Filter in place |
418
+ | `partition(pred)` | Split entries into matching and nonmatching maps |
419
+ | `find(pred)` | Find the first matching entry |
420
+ | `findKey(pred)` / `findValue(pred)` | Find a matching PID or value |
421
+ | `some(pred)` / `every(pred)` | Predicate checks |
422
+ | `reduce(fn, initial)` | Reduce entries |
423
+ | `forEachKV(fn)` | Iterate over value, PID, and map |
424
+ | `invert()` | Reverse PIDs and values into a plain `Map` |
425
+ | `group(fn)` | Group values by computed key, into a map of arrays |
426
+ | `unique(fn?)` | Deduplicate by computed or original value |
427
+ | `pick(pids)` / `omit(pids)` | Select or exclude PIDs |
428
+ | `merge(entries)` | Merge entries into the current map |
429
+ | `clearAndSet(entries)` | Replace all entries as a single batch |
430
+ | `toObject()` | Convert entries to an object |
431
+ | `toArray()` / `toKeys()` / `toValues()` | Convert entries, PIDs, or values to an array |
432
+ | `clone()` | Create a shallow copy |
433
+ | `equals(other)` | Compare PIDs and values by value-aware equality |
434
+ | `on(fn)` | Subscribe to change events; returns an unsubscribe function |
435
+ | `off(fn)` | Unsubscribe a listener |
436
+ | `batch(fn)` | Run multiple writes, coalescing into one event per PID |
437
+ | `dv(pid, deps, fn)` | Define a derived value computed from other PIDs |
438
+ | `dirty(...pids)` | Mark derived values as needing recomputation |
439
+ | `$debug(limit?)` | Enable event history tracking |
440
+ | `$strict()` | Throw if mutated while iterating |
441
+ | `$history()` | Return recorded change events |
442
+ | `$why(pid)` | Return the most recent event for a PID |
443
+ | `$diff(other)` | Compare against another map: added, deleted, and changed entries |
444
+ | `fromObject(obj, cap, stride?)` | Create a map from an object |
445
+ | `fromEntries(entries, cap, stride?)` | Create a map from entries |
446
+ | `from(map, cap, stride?)` | Create a map from another map |
447
+
448
+ `cap`, `stride`, and `size` are exposed as readonly properties. `pidToSlot`, `slotToPid`, and `vals` are the backing arrays.
449
+
324
450
  ## `N2` — Number
325
451
 
326
452
  Numeric helpers return `N2I` for chaining unless otherwise indicated.
@@ -478,46 +604,93 @@ Also inherits the native `String` API. `S2` is registered as a callable and cons
478
604
 
479
605
  ## `SET2` — Set
480
606
 
481
- Extends `Set<T>` with convenience accessors, set algebra, predicate operations, and conversions.
607
+ `SET2` extends `Set` and retains the standard `Set` API, plus functional transforms, bulk mutation, set algebra, and conversion helpers. Like `M2`, keys are arbitrary — any value `Set` accepts, `SET2` accepts.
482
608
 
483
609
  | Method | Description |
484
610
  |---|---|
485
611
  | `s(value)` | Alias for `add` |
486
- | `take(value)` | Deletes and returns the value if present |
487
- | `peek(value)` | Returns the value if present, otherwise `false` |
488
- | `toggle(value)` | Adds an absent value or deletes a present value |
489
- | `first()` / `last()` | Gets the first or last iterated value |
490
- | `union(other)` | Returns the union |
491
- | `intersection(other)` | Returns the intersection |
492
- | `difference(other)` | Returns values absent from another iterable |
493
- | `symmetricDifference(other)` | Returns values exclusive to either set |
494
- | `isSubsetOf(other)` / `isSupersetOf(other)` | Checks subset or superset relationships |
495
- | `isDisjointFrom(other)` | Checks whether sets have no shared values |
496
- | `equals(other)` | Checks set equality |
497
- | `filter(fn)` / `map(fn)` | Filters or transforms values into a `SET2I` |
498
- | `partition(fn)` | Splits values into matching and nonmatching sets |
499
- | `differenceBy(other, fn)` | Computes a difference using computed keys |
500
- | `uniqueBy(fn)` | Keeps the first value for each computed key |
501
- | `find(fn)` | Returns the first matching value |
502
- | `every(fn)` / `some(fn)` | Tests values against a predicate |
503
- | `reduce(fn, initial)` | Reduces values to an accumulated result |
504
- | `addAll(values)` | Adds multiple values |
505
- | `deleteAll(values)` | Deletes values and returns the deletion count |
506
- | `retainAll(values)` | Keeps only values present in another iterable |
507
- | `update(values)` | Adds values from another iterable |
508
- | `replace(values)` | Replaces all members |
509
- | `swap(a, b)` | Removes `a` and adds `b` if `a` exists |
510
- | `clone()` | Creates a copy |
511
- | `toArray()` | Converts to an array |
512
- | `toMap(fn)` | Converts values into a map using returned key-value pairs |
513
- | `toObject(fn?)` | Converts values to an object using generated or stringified keys |
514
- | `toJSON()` | Returns the values as an array |
612
+ | `take(value)` | Delete and return the value, or `undefined` if absent |
613
+ | `peek(value)` | Return the value or `false` if absent |
614
+ | `toggle(value)` | Add if absent, delete if present; returns the new membership |
615
+ | `first()` / `last()` | First or last value in iteration order |
616
+ | `union(other)` | New set of all values in either set |
617
+ | `intersection(other)` | New set of values in both sets |
618
+ | `difference(other)` | New set of values in this set but not the other |
619
+ | `symmetricDifference(other)` | New set of values in either set but not both |
620
+ | `isSubsetOf(other)` / `isSupersetOf(other)` | Containment checks |
621
+ | `isDisjointFrom(other)` | Whether the two sets share no values |
622
+ | `equals(other)` | Whether the two sets contain the same values |
623
+ | `filter(fn)` | New set of values matching the predicate |
624
+ | `map(fn)` | New set of mapped values |
625
+ | `partition(fn)` | Split into matching and nonmatching sets |
626
+ | `differenceBy(other, fn)` | Difference by computed key |
627
+ | `uniqueBy(fn)` | Deduplicate by computed key |
628
+ | `find(fn)` | First matching value, or `undefined` |
629
+ | `every(fn)` / `some(fn)` | Predicate checks |
630
+ | `reduce(fn, initial)` | Reduce values |
631
+ | `addAll(values)` | Add many values |
632
+ | `deleteAll(values)` | Delete many values; returns the count removed |
633
+ | `retainAll(values)` | Delete every value not in `values` |
634
+ | `update(values)` | Alias for `addAll` |
635
+ | `replace(values)` | Clear, then add all values |
636
+ | `swap(a, b)` | If `a` is present, delete `a` and add `b` |
637
+ | `clone()` | Create a shallow copy |
638
+ | `toArray()` | Convert to an array |
639
+ | `toMap(fn)` | Convert to an `M2`, using `fn` to produce `[key, value]` per entry |
640
+ | `toObject(fn?)` | Convert to an object, keyed by `fn(value)` or `String(value)` |
641
+ | `toJSON()` | Alias for `toArray` |
642
+ | `fromArray(values)` | Create a set from an array |
643
+ | `fromObject(obj)` | Create a set from an object's values |
644
+ | `fromEntries(entries)` | Create a set from the values of `[key, value]` pairs |
645
+ | `from(values)` | Create a set from any iterable |
515
646
 
516
- Static constructors: `fromArray(values)`, `fromObject(obj)`, `fromEntries(entries)`, and `from(values)`.
647
+ ## `SET2B` — Set Binary
517
648
 
649
+ `SET2BI` is the dense, PID-indexed backing store for `SET2`. Membership lives in a `Uint8Array` (`flags[pid] → 0/1`), dense iteration walks `slots`, and `pidToIdx` gives O(1) delete via swap-remove. `cap` is the maximum PID; values outside `[0, cap)` read as absent.
518
650
 
651
+ | Method | Description |
652
+ |---|---|
653
+ | `s(pid)` | Alias for `add` |
654
+ | `add(pid)` | Add a PID |
655
+ | `has(pid)` | Whether the PID is a member |
656
+ | `delete(pid)` | Remove a PID; returns whether it was present |
657
+ | `clear()` | Remove every member in place |
658
+ | `take(pid)` | Delete and return the PID, or `undefined` if absent |
659
+ | `peek(pid)` | Return the PID or `false` if absent |
660
+ | `toggle(pid)` | Add if absent, delete if present; returns the new membership |
661
+ | `first()` / `last()` | First or last PID in dense order |
662
+ | `union(other)` | New set of all PIDs in either set |
663
+ | `intersection(other)` | New set of PIDs in both sets |
664
+ | `difference(other)` | New set of PIDs in this set but not the other |
665
+ | `symmetricDifference(other)` | New set of PIDs in either set but not both |
666
+ | `isSubsetOf(other)` / `isSupersetOf(other)` | Containment checks |
667
+ | `isDisjointFrom(other)` | Whether the two sets share no PIDs |
668
+ | `equals(other)` | Whether the two sets contain the same PIDs |
669
+ | `filter(fn)` | New set of PIDs matching the predicate |
670
+ | `map(fn)` | New set of mapped PIDs |
671
+ | `partition(fn)` | Split into matching and nonmatching sets |
672
+ | `differenceBy(other, fn)` | Difference by computed key |
673
+ | `uniqueBy(fn)` | Deduplicate by computed key |
674
+ | `find(fn)` | First matching PID, or `undefined` |
675
+ | `every(fn)` / `some(fn)` | Predicate checks |
676
+ | `reduce(fn, initial)` | Reduce PIDs |
677
+ | `addAll(pids)` | Add many PIDs |
678
+ | `deleteAll(pids)` | Delete many PIDs; returns the count removed |
679
+ | `retainAll(pids)` | Delete every PID not in `pids` |
680
+ | `update(pids)` | Alias for `addAll` |
681
+ | `replace(pids)` | Clear, then add all PIDs |
682
+ | `swap(a, b)` | If `a` is present, delete `a` and add `b` |
683
+ | `clone()` | Create a shallow copy |
684
+ | `toArray()` | Convert to an array of PIDs |
685
+ | `toMap(fn)` | Convert to a plain `Map`, using `fn` to produce `[key, value]` per PID |
686
+ | `toObject(fn?)` | Convert to an object, keyed by `fn(pid)` or `String(pid)` |
687
+ | `toJSON()` | Alias for `toArray` |
688
+ | `fromArray(pids, cap?)` | Create a set from an array of PIDs |
689
+ | `fromObject(obj, cap?)` | Create a set from an object's values |
690
+ | `fromEntries(entries, cap?)` | Create a set from the values of `[key, value]` pairs |
691
+ | `from(pids, cap?)` | Create a set from any iterable of PIDs |
519
692
 
520
- ## `U82` — Array
693
+ ## `U82` — Uint8Array
521
694
 
522
695
  Extends `Array<T>` with collection access, transformations, set-like operations, and in-place utilities.
523
696
 
@@ -678,3 +851,11 @@ const error = ER2.from("Something failed");
678
851
  error.toJSON();
679
852
  ```
680
853
 
854
+
855
+
856
+
857
+
858
+
859
+ </div>
860
+ <div style="font-size: 9px; text-align: right">
861
+