@portel/photon-core 2.5.3 → 2.6.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/README.md CHANGED
@@ -510,6 +510,104 @@ See [CHANNELS.md](./CHANNELS.md) for full architecture documentation.
510
510
 
511
511
  ---
512
512
 
513
+ ### Managed Collections
514
+
515
+ Reactive collections that auto-emit events on mutations, enabling seamless real-time sync between server and client.
516
+
517
+ #### Level 1: Zero Effort (just import)
518
+
519
+ ```typescript
520
+ import { PhotonMCP } from '@portel/photon-core';
521
+
522
+ export default class TodoList extends PhotonMCP {
523
+ items: Task[] = []; // Compiler transforms to ReactiveArray
524
+
525
+ async add(text: string) {
526
+ this.items.push({ id: crypto.randomUUID(), text });
527
+ // Auto-emits 'items:added' — no manual wiring
528
+ }
529
+ }
530
+ ```
531
+
532
+ The compiler detects `extends PhotonMCP` with `= []` array initializers and transforms them to `ReactiveArray` instances. The runtime auto-wires `_propertyName` and `_emitter` after instantiation.
533
+
534
+ **Available reactive types:** `Array` (alias for `ReactiveArray`), `Map` (`ReactiveMap`), `Set` (`ReactiveSet`)
535
+
536
+ **Event naming (Firebase-style):**
537
+
538
+ | Operation | Event | Data |
539
+ |-----------|-------|------|
540
+ | `push(item)` | `{prop}:added` | The item |
541
+ | `pop()` / `splice(i, 1)` | `{prop}:removed` | The removed item |
542
+ | `set(i, val)` | `{prop}:updated` | `{ index, value, previous }` |
543
+ | `replaceAll(items)` | `{prop}:changed` | All items |
544
+
545
+ #### Level 2: Rich Collections
546
+
547
+ `Collection<T>` extends `ReactiveArray<T>` with Laravel-style query chaining and auto-UI rendering hints.
548
+
549
+ ```typescript
550
+ import { PhotonMCP, Collection } from '@portel/photon-core';
551
+
552
+ type Product = { name: string; price: number; stock: number; category: string };
553
+
554
+ export default class ProductCatalog extends PhotonMCP {
555
+ products = new Collection<Product>();
556
+
557
+ async catalog() {
558
+ return this.products.where('stock', '>', 0).sortBy('price');
559
+ }
560
+
561
+ async dashboard() {
562
+ return this.products.where('category', 'Electronics').as('cards');
563
+ }
564
+
565
+ async cheapest() {
566
+ return this.products.sortBy('price').first();
567
+ }
568
+ }
569
+ ```
570
+
571
+ **Query methods** (immutable — return new `Collection<T>`):
572
+
573
+ | Method | Example |
574
+ |--------|---------|
575
+ | `where(key, op?, val)` | `.where('price', '>', 100)` or `.where('status', 'active')` |
576
+ | `query(fn)` | `.query(p => p.stock > 0)` |
577
+ | `collect(fn)` | `.collect(p => ({ ...p, label: p.name }))` |
578
+ | `pluck(key)` | `.pluck('name')` → `Collection<string>` |
579
+ | `sortBy(key \| fn, dir?)` | `.sortBy('price', 'desc')` |
580
+ | `groupBy(key \| fn)` | `.groupBy('category')` → `Record<string, Collection<T>>` |
581
+ | `unique(key?)` | `.unique('category')` |
582
+ | `take(n)` / `skip(n)` | `.take(10)` |
583
+
584
+ **Terminal methods:**
585
+
586
+ | Method | Return |
587
+ |--------|--------|
588
+ | `first(fn?)` / `last(fn?)` | `T \| undefined` |
589
+ | `count()` / `isEmpty()` | `number` / `boolean` |
590
+ | `sum(key?)` / `avg(key?)` | `number` |
591
+ | `min(key?)` / `max(key?)` | `T \| undefined` |
592
+ | `aggregate(fn, init)` | `U` |
593
+
594
+ **Rendering hints** for auto-UI:
595
+
596
+ ```typescript
597
+ // .as() attaches a format hint — auto-UI renders accordingly
598
+ this.products.where('stock', '>', 0).as('table');
599
+ this.products.where('category', 'Electronics').as('cards');
600
+ ```
601
+
602
+ Formats: `'table'` | `'cards'` | `'list'` | `'chart'` | `'grid'` | `'chips'`
603
+
604
+ Without `.as()`, `toJSON()` returns a plain array (backward compatible). With `.as()`, it returns:
605
+ ```json
606
+ { "_photonType": "collection:cards", "items": [...], "count": 3 }
607
+ ```
608
+
609
+ ---
610
+
513
611
  ## 🏗️ Building Custom Runtimes
514
612
 
515
613
  Photon Core is designed to be the foundation for custom runtimes. Here are examples:
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Collection<T> — Rich queryable collection with Laravel-style chaining
3
+ *
4
+ * Extends ReactiveArray<T> so mutations auto-emit events. Query methods return
5
+ * new immutable Collection instances (no emitter wired) that can be further
6
+ * chained or serialized.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { PhotonMCP, Collection } from '@portel/photon-core';
11
+ *
12
+ * export default class ProductCatalog extends PhotonMCP {
13
+ * products = new Collection<Product>();
14
+ *
15
+ * async catalog() {
16
+ * return this.products.where('stock', '>', 0).sortBy('price');
17
+ * }
18
+ *
19
+ * async dashboard() {
20
+ * return this.products.where('category', 'Electronics').as('cards');
21
+ * }
22
+ * }
23
+ * ```
24
+ */
25
+ import { ReactiveArray, type Emitter } from './ReactiveArray.js';
26
+ /** Comparison operators for where() clauses */
27
+ export type CompareOp = '=' | '!=' | '>' | '<' | '>=' | '<=' | '===';
28
+ /** Rendering format hints for auto-UI */
29
+ export type RenderFormat = 'table' | 'cards' | 'list' | 'chart' | 'grid' | 'chips';
30
+ /** Rendering hint attached via .as() */
31
+ export interface RenderHint {
32
+ format: RenderFormat;
33
+ options?: Record<string, unknown>;
34
+ }
35
+ export declare class Collection<T> extends ReactiveArray<T> {
36
+ /** Rendering hint set by .as() */
37
+ _renderHint: RenderHint | null;
38
+ /**
39
+ * Create a new Collection with optional initial items.
40
+ * Items are loaded without triggering events.
41
+ */
42
+ constructor(items?: T[]);
43
+ /**
44
+ * Create a Collection bound to a property name and emitter (for runtime wiring).
45
+ */
46
+ static create<T>(propertyName: string, emitter: Emitter, initialItems?: T[]): Collection<T>;
47
+ /**
48
+ * Create a Collection from an existing array.
49
+ */
50
+ static from<T>(items: T[]): Collection<T>;
51
+ private _result;
52
+ /**
53
+ * Filter items by field comparison.
54
+ *
55
+ * Shorthand: `where('status', 'active')` → equality check
56
+ * Full: `where('price', '>', 100)` → comparison
57
+ */
58
+ where(key: keyof T & string, opOrVal: CompareOp | T[keyof T], val?: T[keyof T]): Collection<T>;
59
+ /**
60
+ * Filter items with a predicate function.
61
+ */
62
+ query(fn: (item: T) => boolean): Collection<T>;
63
+ /**
64
+ * Transform each item.
65
+ */
66
+ collect<U>(fn: (item: T) => U): Collection<U>;
67
+ /**
68
+ * Extract a single field from each item.
69
+ */
70
+ pluck<K extends keyof T>(key: K): Collection<T[K]>;
71
+ /**
72
+ * Sort by a key or comparator function.
73
+ * Returns a new sorted Collection (does NOT mutate).
74
+ */
75
+ sortBy(keyOrFn: (keyof T & string) | ((a: T, b: T) => number), direction?: 'asc' | 'desc'): Collection<T>;
76
+ /**
77
+ * Group items by a key or function.
78
+ * Returns a record of group-name → Collection.
79
+ */
80
+ groupBy(keyOrFn: (keyof T & string) | ((item: T) => string)): Record<string, Collection<T>>;
81
+ /**
82
+ * Remove duplicates, optionally by a key.
83
+ */
84
+ unique(key?: keyof T & string): Collection<T>;
85
+ /**
86
+ * Take the first n items.
87
+ */
88
+ take(n: number): Collection<T>;
89
+ /**
90
+ * Skip the first n items.
91
+ */
92
+ skip(n: number): Collection<T>;
93
+ /**
94
+ * Get the first item, optionally matching a predicate.
95
+ */
96
+ first(fn?: (item: T) => boolean): T | undefined;
97
+ /**
98
+ * Get the last item, optionally matching a predicate.
99
+ */
100
+ last(fn?: (item: T) => boolean): T | undefined;
101
+ /**
102
+ * Count items.
103
+ */
104
+ count(): number;
105
+ /**
106
+ * Check if collection is empty.
107
+ */
108
+ isEmpty(): boolean;
109
+ /**
110
+ * Sum numeric values, optionally by key.
111
+ */
112
+ sum(key?: keyof T & string): number;
113
+ /**
114
+ * Average of numeric values, optionally by key.
115
+ */
116
+ avg(key?: keyof T & string): number;
117
+ /**
118
+ * Item with minimum value (by key or raw comparison).
119
+ */
120
+ min(key?: keyof T & string): T | undefined;
121
+ /**
122
+ * Item with maximum value (by key or raw comparison).
123
+ */
124
+ max(key?: keyof T & string): T | undefined;
125
+ /**
126
+ * Reduce the collection to a single value.
127
+ */
128
+ aggregate<U>(fn: (acc: U, item: T) => U, initial: U): U;
129
+ /**
130
+ * Attach a rendering hint for auto-UI.
131
+ * Returns `this` for chaining at the end of a query.
132
+ */
133
+ as(format: RenderFormat, options?: Record<string, unknown>): this;
134
+ /**
135
+ * Custom serialization.
136
+ * - Without `.as()`: plain array (backward compatible)
137
+ * - With `.as()`: metadata object with `_photonType`, items, and count
138
+ */
139
+ toJSON(): T[] | {
140
+ _photonType: string;
141
+ items: T[];
142
+ count: number;
143
+ renderOptions?: Record<string, unknown>;
144
+ };
145
+ }
146
+ //# sourceMappingURL=Collection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Collection.d.ts","sourceRoot":"","sources":["../../src/collections/Collection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,312 @@
1
+ /**
2
+ * Collection<T> — Rich queryable collection with Laravel-style chaining
3
+ *
4
+ * Extends ReactiveArray<T> so mutations auto-emit events. Query methods return
5
+ * new immutable Collection instances (no emitter wired) that can be further
6
+ * chained or serialized.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { PhotonMCP, Collection } from '@portel/photon-core';
11
+ *
12
+ * export default class ProductCatalog extends PhotonMCP {
13
+ * products = new Collection<Product>();
14
+ *
15
+ * async catalog() {
16
+ * return this.products.where('stock', '>', 0).sortBy('price');
17
+ * }
18
+ *
19
+ * async dashboard() {
20
+ * return this.products.where('category', 'Electronics').as('cards');
21
+ * }
22
+ * }
23
+ * ```
24
+ */
25
+ import { ReactiveArray } from './ReactiveArray.js';
26
+ // No-op emitter for query result collections (immutable — no events)
27
+ const NOOP_EMITTER = () => { };
28
+ export class Collection extends ReactiveArray {
29
+ /** Rendering hint set by .as() */
30
+ _renderHint = null;
31
+ /**
32
+ * Create a new Collection with optional initial items.
33
+ * Items are loaded without triggering events.
34
+ */
35
+ constructor(items) {
36
+ super();
37
+ if (items && items.length > 0) {
38
+ globalThis.Array.prototype.push.apply(this, items);
39
+ }
40
+ }
41
+ /**
42
+ * Create a Collection bound to a property name and emitter (for runtime wiring).
43
+ */
44
+ static create(propertyName, emitter, initialItems) {
45
+ const col = new Collection(initialItems);
46
+ col._propertyName = propertyName;
47
+ col._emitter = emitter;
48
+ return col;
49
+ }
50
+ /**
51
+ * Create a Collection from an existing array.
52
+ */
53
+ static from(items) {
54
+ return new Collection(items);
55
+ }
56
+ // ─── Helper: create an immutable query-result Collection ───
57
+ _result(items) {
58
+ const col = new Collection(items);
59
+ col._emitter = NOOP_EMITTER;
60
+ return col;
61
+ }
62
+ // ─── Query Methods (immutable — return new Collection) ───
63
+ /**
64
+ * Filter items by field comparison.
65
+ *
66
+ * Shorthand: `where('status', 'active')` → equality check
67
+ * Full: `where('price', '>', 100)` → comparison
68
+ */
69
+ where(key, opOrVal, val) {
70
+ let op;
71
+ let compareVal;
72
+ if (val === undefined) {
73
+ // Shorthand: where('status', 'active') → equality
74
+ op = '=';
75
+ compareVal = opOrVal;
76
+ }
77
+ else {
78
+ op = opOrVal;
79
+ compareVal = val;
80
+ }
81
+ return this._result(globalThis.Array.prototype.filter.call(this, (item) => {
82
+ const fieldVal = item[key];
83
+ switch (op) {
84
+ case '=': return fieldVal == compareVal;
85
+ case '===': return fieldVal === compareVal;
86
+ case '!=': return fieldVal != compareVal;
87
+ case '>': return fieldVal > compareVal;
88
+ case '<': return fieldVal < compareVal;
89
+ case '>=': return fieldVal >= compareVal;
90
+ case '<=': return fieldVal <= compareVal;
91
+ default: return false;
92
+ }
93
+ }));
94
+ }
95
+ /**
96
+ * Filter items with a predicate function.
97
+ */
98
+ query(fn) {
99
+ return this._result(globalThis.Array.prototype.filter.call(this, fn));
100
+ }
101
+ /**
102
+ * Transform each item.
103
+ */
104
+ collect(fn) {
105
+ return this._result(globalThis.Array.prototype.map.call(this, fn));
106
+ }
107
+ /**
108
+ * Extract a single field from each item.
109
+ */
110
+ pluck(key) {
111
+ return this._result(globalThis.Array.prototype.map.call(this, (item) => item[key]));
112
+ }
113
+ /**
114
+ * Sort by a key or comparator function.
115
+ * Returns a new sorted Collection (does NOT mutate).
116
+ */
117
+ sortBy(keyOrFn, direction = 'asc') {
118
+ const items = globalThis.Array.from(this);
119
+ if (typeof keyOrFn === 'function') {
120
+ items.sort(keyOrFn);
121
+ }
122
+ else {
123
+ const key = keyOrFn;
124
+ items.sort((a, b) => {
125
+ const aVal = a[key];
126
+ const bVal = b[key];
127
+ if (aVal < bVal)
128
+ return direction === 'asc' ? -1 : 1;
129
+ if (aVal > bVal)
130
+ return direction === 'asc' ? 1 : -1;
131
+ return 0;
132
+ });
133
+ }
134
+ return this._result(items);
135
+ }
136
+ /**
137
+ * Group items by a key or function.
138
+ * Returns a record of group-name → Collection.
139
+ */
140
+ groupBy(keyOrFn) {
141
+ const groups = {};
142
+ for (let i = 0; i < this.length; i++) {
143
+ const item = this[i];
144
+ const groupKey = typeof keyOrFn === 'function'
145
+ ? keyOrFn(item)
146
+ : String(item[keyOrFn]);
147
+ if (!groups[groupKey])
148
+ groups[groupKey] = [];
149
+ groups[groupKey].push(item);
150
+ }
151
+ const result = {};
152
+ for (const [k, v] of Object.entries(groups)) {
153
+ result[k] = this._result(v);
154
+ }
155
+ return result;
156
+ }
157
+ /**
158
+ * Remove duplicates, optionally by a key.
159
+ */
160
+ unique(key) {
161
+ const seen = new globalThis.Set();
162
+ const items = [];
163
+ for (let i = 0; i < this.length; i++) {
164
+ const item = this[i];
165
+ const val = key ? item[key] : item;
166
+ if (!seen.has(val)) {
167
+ seen.add(val);
168
+ items.push(item);
169
+ }
170
+ }
171
+ return this._result(items);
172
+ }
173
+ /**
174
+ * Take the first n items.
175
+ */
176
+ take(n) {
177
+ return this._result(globalThis.Array.prototype.slice.call(this, 0, n));
178
+ }
179
+ /**
180
+ * Skip the first n items.
181
+ */
182
+ skip(n) {
183
+ return this._result(globalThis.Array.prototype.slice.call(this, n));
184
+ }
185
+ // ─── Terminal Methods ───
186
+ /**
187
+ * Get the first item, optionally matching a predicate.
188
+ */
189
+ first(fn) {
190
+ if (!fn)
191
+ return this[0];
192
+ for (let i = 0; i < this.length; i++) {
193
+ if (fn(this[i]))
194
+ return this[i];
195
+ }
196
+ return undefined;
197
+ }
198
+ /**
199
+ * Get the last item, optionally matching a predicate.
200
+ */
201
+ last(fn) {
202
+ if (!fn)
203
+ return this[this.length - 1];
204
+ for (let i = this.length - 1; i >= 0; i--) {
205
+ if (fn(this[i]))
206
+ return this[i];
207
+ }
208
+ return undefined;
209
+ }
210
+ /**
211
+ * Count items.
212
+ */
213
+ count() {
214
+ return this.length;
215
+ }
216
+ /**
217
+ * Check if collection is empty.
218
+ */
219
+ isEmpty() {
220
+ return this.length === 0;
221
+ }
222
+ /**
223
+ * Sum numeric values, optionally by key.
224
+ */
225
+ sum(key) {
226
+ let total = 0;
227
+ for (let i = 0; i < this.length; i++) {
228
+ const val = key ? this[i][key] : this[i];
229
+ total += Number(val) || 0;
230
+ }
231
+ return total;
232
+ }
233
+ /**
234
+ * Average of numeric values, optionally by key.
235
+ */
236
+ avg(key) {
237
+ if (this.length === 0)
238
+ return 0;
239
+ return this.sum(key) / this.length;
240
+ }
241
+ /**
242
+ * Item with minimum value (by key or raw comparison).
243
+ */
244
+ min(key) {
245
+ if (this.length === 0)
246
+ return undefined;
247
+ let minItem = this[0];
248
+ let minVal = key ? minItem[key] : minItem;
249
+ for (let i = 1; i < this.length; i++) {
250
+ const val = key ? this[i][key] : this[i];
251
+ if (val < minVal) {
252
+ minItem = this[i];
253
+ minVal = val;
254
+ }
255
+ }
256
+ return minItem;
257
+ }
258
+ /**
259
+ * Item with maximum value (by key or raw comparison).
260
+ */
261
+ max(key) {
262
+ if (this.length === 0)
263
+ return undefined;
264
+ let maxItem = this[0];
265
+ let maxVal = key ? maxItem[key] : maxItem;
266
+ for (let i = 1; i < this.length; i++) {
267
+ const val = key ? this[i][key] : this[i];
268
+ if (val > maxVal) {
269
+ maxItem = this[i];
270
+ maxVal = val;
271
+ }
272
+ }
273
+ return maxItem;
274
+ }
275
+ /**
276
+ * Reduce the collection to a single value.
277
+ */
278
+ aggregate(fn, initial) {
279
+ let acc = initial;
280
+ for (let i = 0; i < this.length; i++) {
281
+ acc = fn(acc, this[i]);
282
+ }
283
+ return acc;
284
+ }
285
+ // ─── Rendering Hints ───
286
+ /**
287
+ * Attach a rendering hint for auto-UI.
288
+ * Returns `this` for chaining at the end of a query.
289
+ */
290
+ as(format, options) {
291
+ this._renderHint = { format, options };
292
+ return this;
293
+ }
294
+ /**
295
+ * Custom serialization.
296
+ * - Without `.as()`: plain array (backward compatible)
297
+ * - With `.as()`: metadata object with `_photonType`, items, and count
298
+ */
299
+ toJSON() {
300
+ const items = globalThis.Array.from(this);
301
+ if (!this._renderHint) {
302
+ return items;
303
+ }
304
+ return {
305
+ _photonType: `collection:${this._renderHint.format}`,
306
+ items,
307
+ count: items.length,
308
+ ...(this._renderHint.options ? { renderOptions: this._renderHint.options } : {}),
309
+ };
310
+ }
311
+ }
312
+ //# sourceMappingURL=Collection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Collection.js","sourceRoot":"","sources":["../../src/collections/Collection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,aAAa,EAAgB,MAAM,oBAAoB,CAAC;AAcjE,qEAAqE;AACrE,MAAM,YAAY,GAAY,GAAG,EAAE,GAAE,CAAC,CAAC;AAEvC,MAAM,OAAO,UAAc,SAAQ,aAAgB;IACjD,kCAAkC;IAClC,WAAW,GAAsB,IAAI,CAAC;IAEtC;;;OAGG;IACH,YAAY,KAAW;QACrB,KAAK,EAAE,CAAC;QACR,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IAED;;OAEG;IACH,MAAM,CAAU,MAAM,CACpB,YAAoB,EACpB,OAAgB,EAChB,YAAkB;QAElB,MAAM,GAAG,GAAG,IAAI,UAAU,CAAI,YAAY,CAAC,CAAC;QAC3C,GAAW,CAAC,aAAa,GAAG,YAAY,CAAC;QACzC,GAAW,CAAC,QAAQ,GAAG,OAAO,CAAC;QAChC,OAAO,GAAG,CAAC;IACb,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,IAAI,CAAI,KAAU;QACvB,OAAO,IAAI,UAAU,CAAI,KAAK,CAAC,CAAC;IAClC,CAAC;IAED,8DAA8D;IAEtD,OAAO,CAAI,KAAU;QAC3B,MAAM,GAAG,GAAG,IAAI,UAAU,CAAI,KAAK,CAAC,CAAC;QACpC,GAAW,CAAC,QAAQ,GAAG,YAAY,CAAC;QACrC,OAAO,GAAG,CAAC;IACb,CAAC;IAED,4DAA4D;IAE5D;;;;;OAKG;IACH,KAAK,CAAC,GAAqB,EAAE,OAA+B,EAAE,GAAgB;QAC5E,IAAI,EAAa,CAAC;QAClB,IAAI,UAAmB,CAAC;QAExB,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACtB,kDAAkD;YAClD,EAAE,GAAG,GAAG,CAAC;YACT,UAAU,GAAG,OAAO,CAAC;QACvB,CAAC;aAAM,CAAC;YACN,EAAE,GAAG,OAAoB,CAAC;YAC1B,UAAU,GAAG,GAAG,CAAC;QACnB,CAAC;QAED,OAAO,IAAI,CAAC,OAAO,CACjB,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,IAAO,EAAE,EAAE;YACvD,MAAM,QAAQ,GAAI,IAAgC,CAAC,GAAG,CAAC,CAAC;YACxD,QAAQ,EAAE,EAAE,CAAC;gBACX,KAAK,GAAG,CAAC,CAAC,OAAO,QAAQ,IAAI,UAAU,CAAC;gBACxC,KAAK,KAAK,CAAC,CAAC,OAAO,QAAQ,KAAK,UAAU,CAAC;gBAC3C,KAAK,IAAI,CAAC,CAAC,OAAO,QAAQ,IAAI,UAAU,CAAC;gBACzC,KAAK,GAAG,CAAC,CAAC,OAAQ,QAAmB,GAAI,UAAqB,CAAC;gBAC/D,KAAK,GAAG,CAAC,CAAC,OAAQ,QAAmB,GAAI,UAAqB,CAAC;gBAC/D,KAAK,IAAI,CAAC,CAAC,OAAQ,QAAmB,IAAK,UAAqB,CAAC;gBACjE,KAAK,IAAI,CAAC,CAAC,OAAQ,QAAmB,IAAK,UAAqB,CAAC;gBACjE,OAAO,CAAC,CAAC,OAAO,KAAK,CAAC;YACxB,CAAC;QACH,CAAC,CAAQ,CACV,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,EAAwB;QAC5B,OAAO,IAAI,CAAC,OAAO,CACjB,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAQ,CACxD,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,OAAO,CAAI,EAAkB;QAC3B,OAAO,IAAI,CAAC,OAAO,CACjB,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAQ,CACrD,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAoB,GAAM;QAC7B,OAAO,IAAI,CAAC,OAAO,CACjB,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,IAAO,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAW,CAC5E,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,OAAoD,EAAE,YAA4B,KAAK;QAC5F,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAQ,CAAC;QACjD,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,CAAC;YAClC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACtB,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,GAAG,OAAO,CAAC;YACpB,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;gBAClB,MAAM,IAAI,GAAI,CAA6B,CAAC,GAAG,CAAW,CAAC;gBAC3D,MAAM,IAAI,GAAI,CAA6B,CAAC,GAAG,CAAW,CAAC;gBAC3D,IAAI,IAAI,GAAG,IAAI;oBAAE,OAAO,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACrD,IAAI,IAAI,GAAG,IAAI;oBAAE,OAAO,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACrD,OAAO,CAAC,CAAC;YACX,CAAC,CAAC,CAAC;QACL,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;IAED;;;OAGG;IACH,OAAO,CAAC,OAAiD;QACvD,MAAM,MAAM,GAAwB,EAAE,CAAC;QACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACrC,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;YACrB,MAAM,QAAQ,GAAG,OAAO,OAAO,KAAK,UAAU;gBAC5C,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;gBACf,CAAC,CAAC,MAAM,CAAE,IAAgC,CAAC,OAAO,CAAC,CAAC,CAAC;YACvD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;gBAAE,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC;YAC7C,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC;QACD,MAAM,MAAM,GAAkC,EAAE,CAAC;QACjD,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC5C,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAC9B,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,GAAsB;QAC3B,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,GAAG,EAAW,CAAC;QAC3C,MAAM,KAAK,GAAQ,EAAE,CAAC;QACtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACrC,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;YACrB,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,CAAE,IAAgC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAChE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBACnB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBACd,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnB,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,IAAI,CAAC,CAAS;QACZ,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAQ,CAAC,CAAC;IAChF,CAAC;IAED;;OAEG;IACH,IAAI,CAAC,CAAS;QACZ,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAQ,CAAC,CAAC;IAC7E,CAAC;IAED,2BAA2B;IAE3B;;OAEG;IACH,KAAK,CAAC,EAAyB;QAC7B,IAAI,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC;QACxB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACrC,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBAAE,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC;QAClC,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;OAEG;IACH,IAAI,CAAC,EAAyB;QAC5B,IAAI,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACtC,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC1C,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBAAE,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC;QAClC,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;OAEG;IACH,KAAK;QACH,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED;;OAEG;IACH,OAAO;QACL,OAAO,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,GAAsB;QACxB,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACrC,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,CAAE,IAAI,CAAC,CAAC,CAA6B,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACtE,KAAK,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,GAAsB;QACxB,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,CAAC,CAAC;QAChC,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;IACrC,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,GAAsB;QACxB,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QACxC,IAAI,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,MAAM,GAAG,GAAG,CAAC,CAAC,CAAE,OAAmC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;QACvE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACrC,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,CAAE,IAAI,CAAC,CAAC,CAA6B,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACtE,IAAK,GAAc,GAAI,MAAiB,EAAE,CAAC;gBACzC,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;gBAClB,MAAM,GAAG,GAAG,CAAC;YACf,CAAC;QACH,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,GAAsB;QACxB,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QACxC,IAAI,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,MAAM,GAAG,GAAG,CAAC,CAAC,CAAE,OAAmC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;QACvE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACrC,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,CAAE,IAAI,CAAC,CAAC,CAA6B,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACtE,IAAK,GAAc,GAAI,MAAiB,EAAE,CAAC;gBACzC,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;gBAClB,MAAM,GAAG,GAAG,CAAC;YACf,CAAC;QACH,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;OAEG;IACH,SAAS,CAAI,EAA0B,EAAE,OAAU;QACjD,IAAI,GAAG,GAAG,OAAO,CAAC;QAClB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACrC,GAAG,GAAG,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACzB,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED,0BAA0B;IAE1B;;;OAGG;IACH,EAAE,CAAC,MAAoB,EAAE,OAAiC;QACxD,IAAI,CAAC,WAAW,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;QACvC,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;OAIG;IACH,MAAM;QACJ,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAQ,CAAC;QACjD,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO;YACL,WAAW,EAAE,cAAc,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE;YACpD,KAAK;YACL,KAAK,EAAE,KAAK,CAAC,MAAM;YACnB,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACjF,CAAC;IACJ,CAAC;CACF"}
@@ -51,6 +51,7 @@
51
51
  export { ReactiveArray, type Emitter } from './ReactiveArray.js';
52
52
  export { ReactiveMap } from './ReactiveMap.js';
53
53
  export { ReactiveSet } from './ReactiveSet.js';
54
+ export { Collection, type RenderHint, type RenderFormat, type CompareOp } from './Collection.js';
54
55
  export { ReactiveArray as Array } from './ReactiveArray.js';
55
56
  export { ReactiveMap as Map } from './ReactiveMap.js';
56
57
  export { ReactiveSet as Set } from './ReactiveSet.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/collections/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AAEH,OAAO,EAAE,aAAa,EAAE,KAAK,OAAO,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAI/C,OAAO,EAAE,aAAa,IAAI,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,WAAW,IAAI,GAAG,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,WAAW,IAAI,GAAG,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/collections/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AAEH,OAAO,EAAE,aAAa,EAAE,KAAK,OAAO,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,KAAK,UAAU,EAAE,KAAK,YAAY,EAAE,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAIjG,OAAO,EAAE,aAAa,IAAI,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,WAAW,IAAI,GAAG,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,WAAW,IAAI,GAAG,EAAE,MAAM,kBAAkB,CAAC"}
@@ -51,6 +51,7 @@
51
51
  export { ReactiveArray } from './ReactiveArray.js';
52
52
  export { ReactiveMap } from './ReactiveMap.js';
53
53
  export { ReactiveSet } from './ReactiveSet.js';
54
+ export { Collection } from './Collection.js';
54
55
  // Level 1 exports: Shadow global types for zero-effort reactivity
55
56
  // Just `import { Array } from '@portel/photon-core'` and use normally
56
57
  export { ReactiveArray as Array } from './ReactiveArray.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/collections/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AAEH,OAAO,EAAE,aAAa,EAAgB,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,kEAAkE;AAClE,sEAAsE;AACtE,OAAO,EAAE,aAAa,IAAI,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,WAAW,IAAI,GAAG,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,WAAW,IAAI,GAAG,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/collections/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AAEH,OAAO,EAAE,aAAa,EAAgB,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAsD,MAAM,iBAAiB,CAAC;AAEjG,kEAAkE;AAClE,sEAAsE;AACtE,OAAO,EAAE,aAAa,IAAI,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,WAAW,IAAI,GAAG,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,WAAW,IAAI,GAAG,EAAE,MAAM,kBAAkB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../src/compiler.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAiEH,wBAAsB,eAAe,CACnC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAC9C,OAAO,CAAC,MAAM,CAAC,CAmCjB"}
1
+ {"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../src/compiler.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA2GH,wBAAsB,eAAe,CACnC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAC9C,OAAO,CAAC,MAAM,CAAC,CAmCjB"}