@alloy-js/core 0.21.0-dev.9 → 0.22.0-dev.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/CHANGELOG.md +22 -0
- package/dist/src/reactivity.d.ts.map +1 -1
- package/dist/src/reactivity.js +4 -1
- package/dist/src/reactivity.js.map +1 -1
- package/dist/src/refkey.d.ts.map +1 -1
- package/dist/src/refkey.js +2 -1
- package/dist/src/refkey.js.map +1 -1
- package/dist/src/render.d.ts.map +1 -1
- package/dist/src/render.js +3 -0
- package/dist/src/render.js.map +1 -1
- package/dist/src/scheduler.d.ts +4 -4
- package/dist/src/scheduler.d.ts.map +1 -1
- package/dist/src/scheduler.js +10 -5
- package/dist/src/scheduler.js.map +1 -1
- package/dist/src/symbols/output-scope.js +4 -2
- package/dist/src/symbols/output-scope.js.map +1 -1
- package/dist/src/tracer.js +2 -2
- package/dist/src/tracer.js.map +1 -1
- package/dist/src/utils.d.ts +12 -0
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/src/utils.js +15 -3
- package/dist/src/utils.js.map +1 -1
- package/dist/test/reactivity/circular-reactives.test.js +18 -0
- package/dist/test/reactivity/circular-reactives.test.js.map +1 -1
- package/dist/test/utils.test.js +13 -0
- package/dist/test/utils.test.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/reactivity.ts +4 -1
- package/src/refkey.ts +2 -1
- package/src/render.ts +3 -0
- package/src/scheduler.ts +12 -11
- package/src/symbols/output-scope.ts +4 -4
- package/src/tracer.ts +3 -3
- package/src/utils.tsx +25 -4
- package/temp/api.json +121 -1
- package/test/reactivity/circular-reactives.test.tsx +20 -0
- package/test/utils.test.tsx +18 -0
package/src/render.ts
CHANGED
|
@@ -481,6 +481,7 @@ function appendChild(node: RenderedTextTree, rawChild: Child) {
|
|
|
481
481
|
throw new Error("Unknown intrinsic element");
|
|
482
482
|
}
|
|
483
483
|
} else if (isComponentCreator(child)) {
|
|
484
|
+
// todo: remove this effect (only needed for context, not needed for anything else)
|
|
484
485
|
effect(() => {
|
|
485
486
|
trace(
|
|
486
487
|
TracePhase.render.appendChild,
|
|
@@ -581,6 +582,8 @@ function debugPrintChild(child: Children): string {
|
|
|
581
582
|
return `<${child.name}>`;
|
|
582
583
|
} else if (isRenderableObject(child)) {
|
|
583
584
|
return `CustomChildElement(${JSON.stringify(child)})`;
|
|
585
|
+
} else if (isRefkeyable(child)) {
|
|
586
|
+
return `refkey`;
|
|
584
587
|
} else {
|
|
585
588
|
return JSON.stringify(child);
|
|
586
589
|
}
|
package/src/scheduler.ts
CHANGED
|
@@ -1,24 +1,25 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ReactiveEffect } from "@vue/reactivity";
|
|
2
2
|
|
|
3
3
|
export interface QueueJob {
|
|
4
|
-
():
|
|
4
|
+
run(): void;
|
|
5
5
|
}
|
|
6
6
|
const immediateQueue = new Set<QueueJob>();
|
|
7
7
|
const queue = new Set<QueueJob>();
|
|
8
8
|
const pendingPromises = new Set<Promise<any>>();
|
|
9
9
|
|
|
10
|
-
export function scheduler(
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
) {
|
|
14
|
-
return () => {
|
|
15
|
-
queueJob(jobGetter(), immediate);
|
|
10
|
+
export function scheduler(immediate = false) {
|
|
11
|
+
return function (this: ReactiveEffect) {
|
|
12
|
+
queueJob(this, immediate);
|
|
16
13
|
};
|
|
17
14
|
}
|
|
18
|
-
export function queueJob(job: QueueJob, immediate = false) {
|
|
15
|
+
export function queueJob(job: QueueJob | (() => void), immediate = false) {
|
|
19
16
|
// if we have an immediate job, we don't need to queue the normal job.
|
|
20
17
|
// the set is serving an important purpose here in deduping the effects we run
|
|
21
18
|
// (which in effect coalesces multiple update effects together).
|
|
19
|
+
if (typeof job === "function") {
|
|
20
|
+
job = { run: job };
|
|
21
|
+
}
|
|
22
|
+
|
|
22
23
|
if (immediate) {
|
|
23
24
|
immediateQueue.add(job);
|
|
24
25
|
} else {
|
|
@@ -41,7 +42,7 @@ export function flushJobs() {
|
|
|
41
42
|
// First, run all synchronous jobs
|
|
42
43
|
let job;
|
|
43
44
|
while ((job = takeJob()) !== null) {
|
|
44
|
-
job();
|
|
45
|
+
job.run();
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
// If there are no pending promises, we're done
|
|
@@ -58,7 +59,7 @@ export async function flushJobsAsync() {
|
|
|
58
59
|
// First, run all synchronous jobs
|
|
59
60
|
let job;
|
|
60
61
|
while ((job = takeJob()) !== null) {
|
|
61
|
-
job();
|
|
62
|
+
job.run();
|
|
62
63
|
}
|
|
63
64
|
|
|
64
65
|
// If there are no pending promises, we're done
|
|
@@ -256,9 +256,9 @@ export abstract class OutputScope {
|
|
|
256
256
|
}
|
|
257
257
|
|
|
258
258
|
toString() {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
);
|
|
259
|
+
return untrack(() => {
|
|
260
|
+
const ownerSymbol = this.ownerSymbol ? ` for ${this.ownerSymbol}` : "";
|
|
261
|
+
return `${this.constructor.name} ${this.name}[${this.id}]${ownerSymbol}`;
|
|
262
|
+
});
|
|
263
263
|
}
|
|
264
264
|
}
|
package/src/tracer.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { effect
|
|
1
|
+
import { effect } from "@vue/reactivity";
|
|
2
2
|
import { untrack } from "./reactivity.js";
|
|
3
3
|
import { inspectRefkey, type Refkey } from "./refkey.js";
|
|
4
4
|
import { scheduler } from "./scheduler.js";
|
|
@@ -210,7 +210,7 @@ export function traceEffect(phase: TracePhase, cb: () => string) {
|
|
|
210
210
|
let first = true;
|
|
211
211
|
const triggerIds = new Set<number>();
|
|
212
212
|
|
|
213
|
-
|
|
213
|
+
effect(
|
|
214
214
|
() => {
|
|
215
215
|
if (first) {
|
|
216
216
|
// just track what we need, don't log.
|
|
@@ -222,7 +222,7 @@ export function traceEffect(phase: TracePhase, cb: () => string) {
|
|
|
222
222
|
triggerIds.clear();
|
|
223
223
|
},
|
|
224
224
|
{
|
|
225
|
-
scheduler: scheduler(
|
|
225
|
+
scheduler: scheduler(true),
|
|
226
226
|
onTrigger(event) {
|
|
227
227
|
const id = triggerCount++;
|
|
228
228
|
if (dids.has(id)) {
|
package/src/utils.tsx
CHANGED
|
@@ -56,6 +56,22 @@ export function mapJoin<T, U, V>(
|
|
|
56
56
|
cb: (key: T, value: U, index: number) => V,
|
|
57
57
|
options?: JoinOptions,
|
|
58
58
|
): () => (V | string | undefined | CustomContext)[];
|
|
59
|
+
/**
|
|
60
|
+
* Map a Map to an array using a mapper and place a joiner between each element.
|
|
61
|
+
* Defaults to joining with a newline.
|
|
62
|
+
*
|
|
63
|
+
* @see {@link join} for joining without mapping.
|
|
64
|
+
* @param src - Source map.
|
|
65
|
+
* @param cb - Mapper function.
|
|
66
|
+
* @param options - Join options.
|
|
67
|
+
* @returns The mapped and joined array.
|
|
68
|
+
*
|
|
69
|
+
*/
|
|
70
|
+
export function mapJoin<U, V>(
|
|
71
|
+
src: () => Set<U>,
|
|
72
|
+
cb: (value: U, index: number) => V,
|
|
73
|
+
options?: JoinOptions,
|
|
74
|
+
): () => (V | string | undefined | CustomContext)[];
|
|
59
75
|
/**
|
|
60
76
|
* Map a array or iterator to another array using a mapper and place a joiner
|
|
61
77
|
* between each element. Defaults to joining with a newline.
|
|
@@ -72,7 +88,7 @@ export function mapJoin<T, V>(
|
|
|
72
88
|
options?: JoinOptions,
|
|
73
89
|
): () => (V | string | undefined | CustomContext)[];
|
|
74
90
|
export function mapJoin<T, U, V>(
|
|
75
|
-
src: () => Map<T, U> | T[] | Iterable<T>,
|
|
91
|
+
src: () => Map<T, U> | Set<T> | T[] | Iterable<T>,
|
|
76
92
|
cb: (key: T, valueOrIndex: U | number, index: number) => V,
|
|
77
93
|
rawOptions: JoinOptions = {},
|
|
78
94
|
): () => Children {
|
|
@@ -94,6 +110,7 @@ export function mapJoin<T, U, V>(
|
|
|
94
110
|
const itemsSourceRaw = toRaw(itemsSource);
|
|
95
111
|
let items =
|
|
96
112
|
Array.isArray(itemsSourceRaw) ? (itemsSource as T[]) : [...itemsSource];
|
|
113
|
+
|
|
97
114
|
if (options.skipFalsy) {
|
|
98
115
|
items = items.filter(
|
|
99
116
|
(item) =>
|
|
@@ -103,8 +120,8 @@ export function mapJoin<T, U, V>(
|
|
|
103
120
|
// this is important to access here in reactive context so we are
|
|
104
121
|
// notified of new items from reactives.
|
|
105
122
|
const itemsLen = items.length;
|
|
106
|
-
const compare: any = getCompareFunction(
|
|
107
|
-
const mapper: any = getMapperFunction(
|
|
123
|
+
const compare: any = getCompareFunction(itemsSourceRaw);
|
|
124
|
+
const mapper: any = getMapperFunction(itemsSourceRaw);
|
|
108
125
|
|
|
109
126
|
return untrack(() => {
|
|
110
127
|
let startIndex = 0;
|
|
@@ -160,7 +177,11 @@ export function mapJoin<T, U, V>(
|
|
|
160
177
|
}
|
|
161
178
|
|
|
162
179
|
function getMapperFunction(itemsSource: Map<T, U> | T[] | Iterable<T>) {
|
|
163
|
-
return
|
|
180
|
+
return (
|
|
181
|
+
Array.isArray(itemsSource) ||
|
|
182
|
+
itemsSource instanceof Set ||
|
|
183
|
+
isIterable(itemsSource)
|
|
184
|
+
) ?
|
|
164
185
|
mapArray
|
|
165
186
|
: mapMap;
|
|
166
187
|
}
|
package/temp/api.json
CHANGED
|
@@ -10288,6 +10288,126 @@
|
|
|
10288
10288
|
{
|
|
10289
10289
|
"kind": "Function",
|
|
10290
10290
|
"canonicalReference": "@alloy-js/core!mapJoin:function(2)",
|
|
10291
|
+
"docComment": "/**\n * Map a Map to an array using a mapper and place a joiner between each element.\n * Defaults to joining with a newline.\n *\n * @param src - Source map.\n *\n * @param cb - Mapper function.\n *\n * @param options - Join options.\n *\n * @returns The mapped and joined array.\n *\n * @see\n *\n * {@link join} for joining without mapping.\n */\n",
|
|
10292
|
+
"excerptTokens": [
|
|
10293
|
+
{
|
|
10294
|
+
"kind": "Content",
|
|
10295
|
+
"text": "export declare function mapJoin<U, V>(src: "
|
|
10296
|
+
},
|
|
10297
|
+
{
|
|
10298
|
+
"kind": "Content",
|
|
10299
|
+
"text": "() => "
|
|
10300
|
+
},
|
|
10301
|
+
{
|
|
10302
|
+
"kind": "Reference",
|
|
10303
|
+
"text": "Set",
|
|
10304
|
+
"canonicalReference": "!Set:interface"
|
|
10305
|
+
},
|
|
10306
|
+
{
|
|
10307
|
+
"kind": "Content",
|
|
10308
|
+
"text": "<U>"
|
|
10309
|
+
},
|
|
10310
|
+
{
|
|
10311
|
+
"kind": "Content",
|
|
10312
|
+
"text": ", cb: "
|
|
10313
|
+
},
|
|
10314
|
+
{
|
|
10315
|
+
"kind": "Content",
|
|
10316
|
+
"text": "(value: U, index: number) => V"
|
|
10317
|
+
},
|
|
10318
|
+
{
|
|
10319
|
+
"kind": "Content",
|
|
10320
|
+
"text": ", options?: "
|
|
10321
|
+
},
|
|
10322
|
+
{
|
|
10323
|
+
"kind": "Reference",
|
|
10324
|
+
"text": "JoinOptions",
|
|
10325
|
+
"canonicalReference": "@alloy-js/core!JoinOptions:interface"
|
|
10326
|
+
},
|
|
10327
|
+
{
|
|
10328
|
+
"kind": "Content",
|
|
10329
|
+
"text": "): "
|
|
10330
|
+
},
|
|
10331
|
+
{
|
|
10332
|
+
"kind": "Content",
|
|
10333
|
+
"text": "() => (V | string | undefined | "
|
|
10334
|
+
},
|
|
10335
|
+
{
|
|
10336
|
+
"kind": "Reference",
|
|
10337
|
+
"text": "CustomContext",
|
|
10338
|
+
"canonicalReference": "@alloy-js/core!CustomContext:interface"
|
|
10339
|
+
},
|
|
10340
|
+
{
|
|
10341
|
+
"kind": "Content",
|
|
10342
|
+
"text": ")[]"
|
|
10343
|
+
},
|
|
10344
|
+
{
|
|
10345
|
+
"kind": "Content",
|
|
10346
|
+
"text": ";"
|
|
10347
|
+
}
|
|
10348
|
+
],
|
|
10349
|
+
"fileUrlPath": "src/utils.tsx",
|
|
10350
|
+
"returnTypeTokenRange": {
|
|
10351
|
+
"startIndex": 9,
|
|
10352
|
+
"endIndex": 12
|
|
10353
|
+
},
|
|
10354
|
+
"releaseTag": "Public",
|
|
10355
|
+
"overloadIndex": 2,
|
|
10356
|
+
"parameters": [
|
|
10357
|
+
{
|
|
10358
|
+
"parameterName": "src",
|
|
10359
|
+
"parameterTypeTokenRange": {
|
|
10360
|
+
"startIndex": 1,
|
|
10361
|
+
"endIndex": 4
|
|
10362
|
+
},
|
|
10363
|
+
"isOptional": false
|
|
10364
|
+
},
|
|
10365
|
+
{
|
|
10366
|
+
"parameterName": "cb",
|
|
10367
|
+
"parameterTypeTokenRange": {
|
|
10368
|
+
"startIndex": 5,
|
|
10369
|
+
"endIndex": 6
|
|
10370
|
+
},
|
|
10371
|
+
"isOptional": false
|
|
10372
|
+
},
|
|
10373
|
+
{
|
|
10374
|
+
"parameterName": "options",
|
|
10375
|
+
"parameterTypeTokenRange": {
|
|
10376
|
+
"startIndex": 7,
|
|
10377
|
+
"endIndex": 8
|
|
10378
|
+
},
|
|
10379
|
+
"isOptional": true
|
|
10380
|
+
}
|
|
10381
|
+
],
|
|
10382
|
+
"typeParameters": [
|
|
10383
|
+
{
|
|
10384
|
+
"typeParameterName": "U",
|
|
10385
|
+
"constraintTokenRange": {
|
|
10386
|
+
"startIndex": 0,
|
|
10387
|
+
"endIndex": 0
|
|
10388
|
+
},
|
|
10389
|
+
"defaultTypeTokenRange": {
|
|
10390
|
+
"startIndex": 0,
|
|
10391
|
+
"endIndex": 0
|
|
10392
|
+
}
|
|
10393
|
+
},
|
|
10394
|
+
{
|
|
10395
|
+
"typeParameterName": "V",
|
|
10396
|
+
"constraintTokenRange": {
|
|
10397
|
+
"startIndex": 0,
|
|
10398
|
+
"endIndex": 0
|
|
10399
|
+
},
|
|
10400
|
+
"defaultTypeTokenRange": {
|
|
10401
|
+
"startIndex": 0,
|
|
10402
|
+
"endIndex": 0
|
|
10403
|
+
}
|
|
10404
|
+
}
|
|
10405
|
+
],
|
|
10406
|
+
"name": "mapJoin"
|
|
10407
|
+
},
|
|
10408
|
+
{
|
|
10409
|
+
"kind": "Function",
|
|
10410
|
+
"canonicalReference": "@alloy-js/core!mapJoin:function(3)",
|
|
10291
10411
|
"docComment": "/**\n * Map a array or iterator to another array using a mapper and place a joiner\n * between each element. Defaults to joining with a newline.\n *\n * @param src - Source array.\n *\n * @param cb - Mapper function.\n *\n * @param options - Join options.\n *\n * @returns The mapped and joined array.\n *\n * @see\n *\n * {@link join} for joining without mapping.\n */\n",
|
|
10292
10412
|
"excerptTokens": [
|
|
10293
10413
|
{
|
|
@@ -10352,7 +10472,7 @@
|
|
|
10352
10472
|
"endIndex": 12
|
|
10353
10473
|
},
|
|
10354
10474
|
"releaseTag": "Public",
|
|
10355
|
-
"overloadIndex":
|
|
10475
|
+
"overloadIndex": 3,
|
|
10356
10476
|
"parameters": [
|
|
10357
10477
|
{
|
|
10358
10478
|
"parameterName": "src",
|
|
@@ -30,3 +30,23 @@ it("it should work with circular reactives", () => {
|
|
|
30
30
|
item 1
|
|
31
31
|
`);
|
|
32
32
|
});
|
|
33
|
+
|
|
34
|
+
it("should work with immediately recursive reactives", () => {
|
|
35
|
+
const items: Set<string> = shallowReactive(new Set());
|
|
36
|
+
const template = (
|
|
37
|
+
<>
|
|
38
|
+
<For each={items.values()}>
|
|
39
|
+
{(item) => {
|
|
40
|
+
items.add("item 1");
|
|
41
|
+
return item;
|
|
42
|
+
}}
|
|
43
|
+
</For>
|
|
44
|
+
</>
|
|
45
|
+
);
|
|
46
|
+
const tree = renderTree(template);
|
|
47
|
+
items.add("item start");
|
|
48
|
+
expect(printTree(tree)).toBe(d`
|
|
49
|
+
item start
|
|
50
|
+
item 1
|
|
51
|
+
`);
|
|
52
|
+
});
|
package/test/utils.test.tsx
CHANGED
|
@@ -32,6 +32,24 @@ describe("mapJoin", () => {
|
|
|
32
32
|
`);
|
|
33
33
|
});
|
|
34
34
|
|
|
35
|
+
it("can map a set", () => {
|
|
36
|
+
const set = new Set(["hi", "bye"]);
|
|
37
|
+
|
|
38
|
+
function Foo(props: { value: string }) {
|
|
39
|
+
return <>Value: {props.value}</>;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const joined = mapJoin(
|
|
43
|
+
() => set,
|
|
44
|
+
(value) => <Foo value={value} />,
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
expect(joined()).toRenderTo(`
|
|
48
|
+
Value: hi
|
|
49
|
+
Value: bye
|
|
50
|
+
`);
|
|
51
|
+
});
|
|
52
|
+
|
|
35
53
|
it("can map an array", () => {
|
|
36
54
|
const arr = [1, 2];
|
|
37
55
|
|