@cascateer/core 2.3.50 → 2.4.1
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/.github/workflows/publish.yml +2 -27
- package/.github/workflows/publish2.yml +36 -0
- package/package.json +10 -9
- package/src/api.ts +10 -4
- package/src/app.ts +1 -1
- package/src/component.ts +7 -7
- package/src/css.ts +1 -1
- package/src/fragment.ts +1 -1
- package/src/index.ts +1 -1
- package/src/jsx-runtime.ts +8 -6
- package/src/lib/memoize.ts +5 -0
- package/src/multicast.ts +1 -1
- package/src/observable/index.ts +0 -1
- package/src/operators/exchangeWith.ts +1 -1
- package/src/operators/multicast.ts +4 -3
- package/src/{observable → signal}/Signal.test.ts +5 -5
- package/src/{observable → signal}/Signal.ts +30 -42
- package/src/signal/index.ts +1 -0
- package/src/slice.ts +2 -2
- package/src/store.ts +6 -6
- package/src/terminal.ts +2 -2
- package/src/types.ts +2 -15
- package/src/lib/Enumerable.ts +0 -23
- package/src/lib/ExtendableDictionary.ts +0 -56
- package/src/lib/chunkWith.ts +0 -26
- package/src/lib/index.ts +0 -29
- package/src/lib/keys.ts +0 -7
- package/src/lib/memoizeHashed.ts +0 -5
- package/src/lib/nthArg.ts +0 -6
- package/src/lib/property.ts +0 -4
|
@@ -6,30 +6,5 @@ on:
|
|
|
6
6
|
- "v*"
|
|
7
7
|
|
|
8
8
|
jobs:
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
permissions:
|
|
12
|
-
contents: write
|
|
13
|
-
id-token: write
|
|
14
|
-
|
|
15
|
-
steps:
|
|
16
|
-
- uses: actions/checkout@v6
|
|
17
|
-
- uses: actions/setup-node@v6
|
|
18
|
-
with:
|
|
19
|
-
node-version: "24"
|
|
20
|
-
registry-url: "https://registry.npmjs.org"
|
|
21
|
-
|
|
22
|
-
- name: Verify version matches tag
|
|
23
|
-
run: |
|
|
24
|
-
TAG="${GITHUB_REF#refs/tags/}"
|
|
25
|
-
VERSION="${TAG#v}"
|
|
26
|
-
FILE_VERSION=$(node -p "require('./package.json').version")
|
|
27
|
-
if [ "$VERSION" != "$FILE_VERSION" ]; then
|
|
28
|
-
echo "Version mismatch: tag=$VERSION, package.json=$FILE_VERSION"
|
|
29
|
-
exit 1
|
|
30
|
-
fi
|
|
31
|
-
|
|
32
|
-
- name: Publish to NPM
|
|
33
|
-
env:
|
|
34
|
-
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
35
|
-
run: npm publish --access public --provenance
|
|
9
|
+
call-workflow:
|
|
10
|
+
uses: cascateer/lib/.github/workflows/publish.yml@main
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
name: Publish to NPM
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_call:
|
|
5
|
+
push:
|
|
6
|
+
tags:
|
|
7
|
+
- "v*"
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
publish:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
permissions:
|
|
13
|
+
contents: write
|
|
14
|
+
id-token: write
|
|
15
|
+
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v6
|
|
18
|
+
- uses: actions/setup-node@v6
|
|
19
|
+
with:
|
|
20
|
+
node-version: "24"
|
|
21
|
+
registry-url: "https://registry.npmjs.org"
|
|
22
|
+
|
|
23
|
+
- name: Verify version matches tag
|
|
24
|
+
run: |
|
|
25
|
+
TAG="${GITHUB_REF#refs/tags/}"
|
|
26
|
+
VERSION="${TAG#v}"
|
|
27
|
+
FILE_VERSION=$(node -p "require('./package.json').version")
|
|
28
|
+
if [ "$VERSION" != "$FILE_VERSION" ]; then
|
|
29
|
+
echo "Version mismatch: tag=$VERSION, package.json=$FILE_VERSION"
|
|
30
|
+
exit 1
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
- name: Publish to NPM
|
|
34
|
+
env:
|
|
35
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
36
|
+
run: npm publish --access public --provenance
|
package/package.json
CHANGED
|
@@ -1,34 +1,35 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cascateer/core",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.1",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/cascateer/core.git"
|
|
7
7
|
},
|
|
8
8
|
"scripts": {
|
|
9
9
|
"patch": "npm version patch && git push origin main --tags",
|
|
10
|
+
"update": "npm cache clean --force && npx npm-check-updates -u && npm i",
|
|
10
11
|
"test": "vitest"
|
|
11
12
|
},
|
|
12
13
|
"exports": {
|
|
13
14
|
".": "./src/index.ts",
|
|
14
15
|
"./jsx-runtime": "./src/jsx-runtime.ts",
|
|
15
16
|
"./jsx-dev-runtime": "./src/jsx-dev-runtime.ts",
|
|
16
|
-
"./lib": "./src/lib/index.ts",
|
|
17
17
|
"./operators": "./src/operators/index.ts"
|
|
18
18
|
},
|
|
19
19
|
"devDependencies": {
|
|
20
|
-
"@types/lodash": "^4.17.
|
|
20
|
+
"@types/lodash": "^4.17.24",
|
|
21
21
|
"@types/object-hash": "^3.0.6",
|
|
22
|
-
"@types/react": "^19.2.
|
|
23
|
-
"typescript": "~
|
|
24
|
-
"vite": "^8.0.
|
|
25
|
-
"vitest": "^4.1.
|
|
22
|
+
"@types/react": "^19.2.16",
|
|
23
|
+
"typescript": "~6.0.3",
|
|
24
|
+
"vite": "^8.0.16",
|
|
25
|
+
"vitest": "^4.1.8"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"
|
|
28
|
+
"@cascateer/lib": "^1.0.4",
|
|
29
|
+
"lodash": "^4.18.1",
|
|
29
30
|
"object-hash": "^3.0.0",
|
|
30
31
|
"rxjs": "^7.8.2",
|
|
31
32
|
"ts-brand": "^0.2.0",
|
|
32
|
-
"uuid": "^
|
|
33
|
+
"uuid": "^14.0.0"
|
|
33
34
|
}
|
|
34
35
|
}
|
package/src/api.ts
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
asObservable,
|
|
3
|
+
ExtendableDictionary,
|
|
4
|
+
MaybeArray,
|
|
5
|
+
MaybeObservable,
|
|
6
|
+
property,
|
|
7
|
+
} from "@cascateer/lib";
|
|
1
8
|
import {
|
|
2
9
|
constant,
|
|
3
10
|
Dictionary,
|
|
@@ -19,10 +26,9 @@ import {
|
|
|
19
26
|
tap,
|
|
20
27
|
UnaryFunction,
|
|
21
28
|
} from "rxjs";
|
|
22
|
-
import {
|
|
23
|
-
import { memoizeHashed } from "./lib/memoizeHashed";
|
|
29
|
+
import { memoize } from "./lib/memoize";
|
|
24
30
|
import { ProxyObservable } from "./observable";
|
|
25
|
-
import { Action,
|
|
31
|
+
import { Action, ProxyEffect } from "./types";
|
|
26
32
|
|
|
27
33
|
interface TagsConstructor<Args, Result> {
|
|
28
34
|
(args: Args, result: Result): string[];
|
|
@@ -47,7 +53,7 @@ class Memoizable<Args, Result> {
|
|
|
47
53
|
this.tags = isFunction(tags) ? tags : constant([tags ?? []].flat());
|
|
48
54
|
|
|
49
55
|
this.subscribe = (invalidatedTags) => {
|
|
50
|
-
const memoizedEffect: ProxyEffect<Args, Result> =
|
|
56
|
+
const memoizedEffect: ProxyEffect<Args, Result> = memoize(
|
|
51
57
|
(args) =>
|
|
52
58
|
new ProxyObservable((pending) =>
|
|
53
59
|
this.predicate(args).pipe(
|
package/src/app.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { property } from "@cascateer/lib";
|
|
1
2
|
import { Dictionary, mapValues } from "lodash";
|
|
2
3
|
import { UnaryFunction } from "rxjs";
|
|
3
4
|
import { createFragment } from ".";
|
|
4
|
-
import { property } from "./lib";
|
|
5
5
|
import { Slice, SliceAdapter, SliceProvider } from "./slice";
|
|
6
6
|
|
|
7
7
|
export class App<
|
package/src/component.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
+
import { ExtendableDictionary } from "@cascateer/lib";
|
|
1
2
|
import { Dictionary, kebabCase } from "lodash";
|
|
2
3
|
import { defer, share, UnaryFunction } from "rxjs";
|
|
3
4
|
import { createFragment } from ".";
|
|
4
5
|
import { ApiAdapter, ApiEffect } from "./api";
|
|
5
6
|
import { cssStyleSheets } from "./css";
|
|
6
7
|
import { defineCustomElement } from "./dom";
|
|
7
|
-
import {
|
|
8
|
-
import { ComputedSignal } from "./observable";
|
|
8
|
+
import { ComputedSignal } from "./signal";
|
|
9
9
|
import { asStoreEffects, StoreAdapter, StoreEffects } from "./store";
|
|
10
10
|
import { TerminalAdapter, TerminalEffect } from "./terminal";
|
|
11
11
|
import { Action, Effect } from "./types";
|
|
@@ -18,23 +18,23 @@ export function createComponent(customElement?: string) {
|
|
|
18
18
|
const withTemplate =
|
|
19
19
|
<Styles extends Promise<unknown>[]>(...styles: Styles) =>
|
|
20
20
|
<
|
|
21
|
-
|
|
21
|
+
Context extends Dictionary<Effect<any, any> | Action<any, any>>,
|
|
22
22
|
Props extends JSX.Props,
|
|
23
23
|
>(
|
|
24
24
|
constructor: (
|
|
25
|
-
|
|
25
|
+
ctx: Context,
|
|
26
26
|
...classNamesList: { -readonly [K in keyof Styles]: Awaited<Styles[K]> }
|
|
27
27
|
) => JSX.Component<Props>,
|
|
28
28
|
) =>
|
|
29
29
|
class extends ComponentConstructor<Props> {
|
|
30
|
-
constructor(
|
|
30
|
+
constructor(ctx: Context) {
|
|
31
31
|
super(
|
|
32
32
|
(key) => (props) =>
|
|
33
33
|
createFragment({
|
|
34
34
|
children: defer(() =>
|
|
35
35
|
Promise.all(styles).then((cssModules) =>
|
|
36
|
-
cssStyleSheets(cssModules).then(
|
|
37
|
-
const element = constructor(
|
|
36
|
+
cssStyleSheets(cssModules).then((cssStyleSheets) => {
|
|
37
|
+
const element = constructor(ctx, ...cssModules)(props);
|
|
38
38
|
|
|
39
39
|
return customElement != null
|
|
40
40
|
? new (defineCustomElement(
|
package/src/css.ts
CHANGED
package/src/fragment.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { asArray, asObservable } from "@cascateer/lib";
|
|
1
2
|
import { tap } from "lodash";
|
|
2
3
|
import {
|
|
3
4
|
combineLatest,
|
|
@@ -12,7 +13,6 @@ import {
|
|
|
12
13
|
Subscription,
|
|
13
14
|
switchMap,
|
|
14
15
|
} from "rxjs";
|
|
15
|
-
import { asArray, asObservable } from "./lib";
|
|
16
16
|
import { flatMap } from "./operators";
|
|
17
17
|
|
|
18
18
|
export type Leaf =
|
package/src/index.ts
CHANGED
|
@@ -7,4 +7,4 @@ export { Serializable, type BrandedSerializer } from "./serializable";
|
|
|
7
7
|
export { createSlice } from "./slice";
|
|
8
8
|
export { type StoreEffect } from "./store";
|
|
9
9
|
export { type TerminalEffect } from "./terminal";
|
|
10
|
-
export { type Action, type
|
|
10
|
+
export { type Action, type Effect } from "./types";
|
package/src/jsx-runtime.ts
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
import {
|
|
2
|
+
asArray,
|
|
3
|
+
asObservable,
|
|
4
|
+
keys,
|
|
5
|
+
MaybeArray,
|
|
6
|
+
MaybeObservable,
|
|
7
|
+
MaybeObservableInputTuple,
|
|
8
|
+
} from "@cascateer/lib";
|
|
1
9
|
import { bind, camelCase, isFunction, isObject } from "lodash";
|
|
2
10
|
import React, { CSSProperties } from "react";
|
|
3
11
|
import {
|
|
@@ -9,13 +17,7 @@ import {
|
|
|
9
17
|
UnaryFunction,
|
|
10
18
|
} from "rxjs";
|
|
11
19
|
import { Leaf, ObservableFragment } from "./fragment";
|
|
12
|
-
import { asArray, asObservable, keys } from "./lib";
|
|
13
20
|
import { sequence } from "./operators";
|
|
14
|
-
import {
|
|
15
|
-
MaybeArray,
|
|
16
|
-
MaybeObservable,
|
|
17
|
-
MaybeObservableInputTuple,
|
|
18
|
-
} from "./types";
|
|
19
21
|
|
|
20
22
|
type DocumentEventListener<EventName extends keyof DocumentEventMap> =
|
|
21
23
|
| Partial<Observer<DocumentEventMap[EventName]>>
|
package/src/multicast.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { property } from "@cascateer/lib";
|
|
1
2
|
import { partition, thru, uniq, uniqBy } from "lodash";
|
|
2
3
|
import {
|
|
3
4
|
distinct,
|
|
@@ -11,7 +12,6 @@ import {
|
|
|
11
12
|
share,
|
|
12
13
|
} from "rxjs";
|
|
13
14
|
import { v4 } from "uuid";
|
|
14
|
-
import { property } from "./lib";
|
|
15
15
|
import {
|
|
16
16
|
accumulate,
|
|
17
17
|
exchangeWith,
|
package/src/observable/index.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { EndoFunction } from "@cascateer/lib";
|
|
1
2
|
import { concatMap, shareReplay, startWith, UnaryFunction } from "rxjs";
|
|
2
3
|
import { v4 } from "uuid";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
4
|
+
import { ProxySubject } from "../observable";
|
|
5
|
+
import { ComputedSignal } from "../signal";
|
|
5
6
|
import { exchangeWith } from "./exchangeWith";
|
|
6
7
|
import { proxyReplaySubject } from "./proxyReplaySubject";
|
|
7
8
|
|
|
@@ -22,7 +23,7 @@ interface MulticastActions<Data> {
|
|
|
22
23
|
};
|
|
23
24
|
};
|
|
24
25
|
transformAction: {
|
|
25
|
-
predicate:
|
|
26
|
+
predicate: EndoFunction<Data>;
|
|
26
27
|
data: {
|
|
27
28
|
key: string;
|
|
28
29
|
args: string;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { EndoFunction } from "@cascateer/lib";
|
|
1
2
|
import { identity } from "lodash";
|
|
2
3
|
import {
|
|
3
4
|
lastValueFrom,
|
|
@@ -8,8 +9,7 @@ import {
|
|
|
8
9
|
toArray,
|
|
9
10
|
} from "rxjs";
|
|
10
11
|
import { expect, test } from "vitest";
|
|
11
|
-
import {
|
|
12
|
-
import { ComputedSignal } from "./Signal";
|
|
12
|
+
import { ComputedSignal } from ".";
|
|
13
13
|
|
|
14
14
|
test("projection", () => {
|
|
15
15
|
const signal = new ComputedSignal({
|
|
@@ -22,7 +22,7 @@ test("projection", () => {
|
|
|
22
22
|
});
|
|
23
23
|
|
|
24
24
|
test("transformation", () => {
|
|
25
|
-
const transforms = new ReplaySubject<
|
|
25
|
+
const transforms = new ReplaySubject<EndoFunction<any>>();
|
|
26
26
|
const signal = new ComputedSignal({
|
|
27
27
|
value: transforms.pipe(
|
|
28
28
|
startWith(identity),
|
|
@@ -30,8 +30,8 @@ test("transformation", () => {
|
|
|
30
30
|
),
|
|
31
31
|
}).property("number");
|
|
32
32
|
|
|
33
|
-
transforms.next(signal.
|
|
34
|
-
transforms.next(signal.
|
|
33
|
+
transforms.next(signal.pull((number) => number + 1));
|
|
34
|
+
transforms.next(signal.pull((number) => number + 2));
|
|
35
35
|
transforms.complete();
|
|
36
36
|
|
|
37
37
|
return lastValueFrom(signal.pipe(toArray())).then((numbers) =>
|
|
@@ -1,35 +1,23 @@
|
|
|
1
|
-
import { clone, identity, isEqual, memoize } from "lodash";
|
|
2
|
-
import { distinctUntilChanged, map, Observable, UnaryFunction } from "rxjs";
|
|
3
|
-
import { ProxyObservable } from ".";
|
|
4
1
|
import {
|
|
5
2
|
asEnumerable,
|
|
3
|
+
EndoFunctionOperator,
|
|
6
4
|
EnumerableItem,
|
|
7
5
|
Enumerator,
|
|
8
6
|
nonNullable,
|
|
9
7
|
nthArg,
|
|
10
8
|
property,
|
|
11
|
-
} from "
|
|
12
|
-
import {
|
|
9
|
+
} from "@cascateer/lib";
|
|
10
|
+
import { clone, identity, isEqual, memoize } from "lodash";
|
|
11
|
+
import { distinctUntilChanged, map, Observable, UnaryFunction } from "rxjs";
|
|
12
|
+
import { ProxyObservable } from "../observable";
|
|
13
13
|
|
|
14
14
|
class SignalEnumerator<T> {
|
|
15
|
-
constructor(private
|
|
15
|
+
constructor(private predicate: Enumerator<T> = nthArg(1)) {}
|
|
16
16
|
|
|
17
17
|
findIndex = (key: PropertyKey) => (value: T) =>
|
|
18
|
-
asEnumerable(value).map(this.
|
|
18
|
+
asEnumerable(value).map(this.predicate).indexOf(key);
|
|
19
19
|
|
|
20
|
-
enumerate = (value: T) => asEnumerable(value).map(this.
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
class SignalAdapter<T> {
|
|
24
|
-
constructor(
|
|
25
|
-
public lift: (transform: Transform<T>) => Transform<unknown> = identity,
|
|
26
|
-
) {}
|
|
27
|
-
|
|
28
|
-
connect<U>(
|
|
29
|
-
connector: UnaryFunction<Transform<U>, Transform<T>>,
|
|
30
|
-
): SignalAdapter<U> {
|
|
31
|
-
return new SignalAdapter((transform) => this.lift(connector(transform)));
|
|
32
|
-
}
|
|
20
|
+
enumerate = (value: T) => asEnumerable(value).map(this.predicate);
|
|
33
21
|
}
|
|
34
22
|
|
|
35
23
|
export class Signal<T> extends ProxyObservable<T> {
|
|
@@ -42,42 +30,42 @@ export class Signal<T> extends ProxyObservable<T> {
|
|
|
42
30
|
}
|
|
43
31
|
|
|
44
32
|
enumerator: SignalEnumerator<T>;
|
|
45
|
-
|
|
33
|
+
pull: EndoFunctionOperator<T, unknown>;
|
|
46
34
|
|
|
47
35
|
constructor({
|
|
48
36
|
value,
|
|
49
37
|
enumerator = new SignalEnumerator(),
|
|
50
|
-
|
|
38
|
+
pull = identity,
|
|
51
39
|
}: {
|
|
52
40
|
value: Observable<T>;
|
|
53
41
|
enumerator?: SignalEnumerator<T>;
|
|
54
|
-
|
|
42
|
+
pull?: EndoFunctionOperator<T, unknown>;
|
|
55
43
|
}) {
|
|
56
44
|
super(value);
|
|
57
45
|
|
|
58
46
|
this.enumerator = enumerator;
|
|
59
|
-
this.
|
|
47
|
+
this.pull = pull;
|
|
60
48
|
}
|
|
61
49
|
|
|
62
|
-
private
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
50
|
+
private map<U>(
|
|
51
|
+
project: UnaryFunction<T, U>,
|
|
52
|
+
lift: EndoFunctionOperator<U, T>,
|
|
53
|
+
enumerate?: Enumerator<U>,
|
|
66
54
|
): Signal<U> {
|
|
67
55
|
return new Signal({
|
|
68
|
-
value: this.pipe(map(
|
|
69
|
-
enumerator: new SignalEnumerator(
|
|
70
|
-
|
|
56
|
+
value: this.pipe(map(project), distinctUntilChanged()),
|
|
57
|
+
enumerator: new SignalEnumerator(enumerate),
|
|
58
|
+
pull: (transform) => this.pull(lift(transform)),
|
|
71
59
|
});
|
|
72
60
|
}
|
|
73
61
|
|
|
74
62
|
protected property<K extends keyof T>(
|
|
75
63
|
key: K,
|
|
76
|
-
|
|
64
|
+
enumerate?: Enumerator<T[K]>,
|
|
77
65
|
): Signal<T[K]> {
|
|
78
66
|
const findProperty: UnaryFunction<T, T[K]> = property(key);
|
|
79
67
|
|
|
80
|
-
return this.
|
|
68
|
+
return this.map(
|
|
81
69
|
findProperty,
|
|
82
70
|
(transform) => (value) => {
|
|
83
71
|
value = clone(value);
|
|
@@ -86,19 +74,19 @@ export class Signal<T> extends ProxyObservable<T> {
|
|
|
86
74
|
|
|
87
75
|
return value;
|
|
88
76
|
},
|
|
89
|
-
|
|
77
|
+
enumerate,
|
|
90
78
|
);
|
|
91
79
|
}
|
|
92
80
|
|
|
93
81
|
protected item(
|
|
94
82
|
key: PropertyKey,
|
|
95
|
-
|
|
83
|
+
enumerate?: Enumerator<EnumerableItem<T>>,
|
|
96
84
|
): Signal<EnumerableItem<T>> {
|
|
97
85
|
const findIndex = this.enumerator.findIndex(key);
|
|
98
86
|
const findItem: UnaryFunction<T, EnumerableItem<T>> = (value) =>
|
|
99
87
|
nonNullable(asEnumerable(value)[findIndex(value)]);
|
|
100
88
|
|
|
101
|
-
return this.
|
|
89
|
+
return this.map(
|
|
102
90
|
findItem,
|
|
103
91
|
(transform) => (value) => {
|
|
104
92
|
if (Array.isArray((value = clone(value)))) {
|
|
@@ -107,14 +95,14 @@ export class Signal<T> extends ProxyObservable<T> {
|
|
|
107
95
|
|
|
108
96
|
return value;
|
|
109
97
|
},
|
|
110
|
-
|
|
98
|
+
enumerate,
|
|
111
99
|
);
|
|
112
100
|
}
|
|
113
101
|
|
|
114
102
|
protected collection<K extends keyof EnumerableItem<T>>(
|
|
115
103
|
key: K,
|
|
116
104
|
): Signal<EnumerableItem<T>[K][]> {
|
|
117
|
-
return this.
|
|
105
|
+
return this.map(
|
|
118
106
|
(value) => asEnumerable(value).map(property(key)),
|
|
119
107
|
(transform) => (value) => {
|
|
120
108
|
if (Array.isArray((value = clone(value)))) {
|
|
@@ -150,16 +138,16 @@ export class Signal<T> extends ProxyObservable<T> {
|
|
|
150
138
|
export class ComputedSignal<T> extends Signal<T> {
|
|
151
139
|
property<K extends keyof T>(
|
|
152
140
|
key: K,
|
|
153
|
-
|
|
141
|
+
enumerate?: Enumerator<T[K]>,
|
|
154
142
|
): ComputedSignal<T[K]> {
|
|
155
|
-
return new ComputedSignal(super.property(key,
|
|
143
|
+
return new ComputedSignal(super.property(key, enumerate));
|
|
156
144
|
}
|
|
157
145
|
|
|
158
146
|
item(
|
|
159
147
|
key: PropertyKey,
|
|
160
|
-
|
|
148
|
+
enumerate?: Enumerator<EnumerableItem<T>>,
|
|
161
149
|
): ComputedSignal<EnumerableItem<T>> {
|
|
162
|
-
return new ComputedSignal(super.item(key,
|
|
150
|
+
return new ComputedSignal(super.item(key, enumerate));
|
|
163
151
|
}
|
|
164
152
|
|
|
165
153
|
collection<K extends keyof EnumerableItem<T>>(
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ComputedSignal, Signal } from "./Signal";
|
package/src/slice.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ExtendableDictionary } from "@cascateer/lib";
|
|
1
2
|
import { Dictionary, mapValues } from "lodash";
|
|
2
3
|
import { defer, map, share, UnaryFunction } from "rxjs";
|
|
3
4
|
import { createFragment } from ".";
|
|
@@ -8,9 +9,8 @@ import {
|
|
|
8
9
|
ComponentsProvider,
|
|
9
10
|
} from "./component";
|
|
10
11
|
import { defineCustomElement } from "./dom";
|
|
11
|
-
import { ExtendableDictionary } from "./lib";
|
|
12
|
-
import { ComputedSignal } from "./observable";
|
|
13
12
|
import { multicast, MulticastSubject } from "./operators";
|
|
13
|
+
import { ComputedSignal } from "./signal";
|
|
14
14
|
import { StoreAdapter, StoreProvider } from "./store";
|
|
15
15
|
import { TerminalAdapter, TerminalEffect, TerminalProvider } from "./terminal";
|
|
16
16
|
import { Action } from "./types";
|
package/src/store.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { EndoFunction, ExtendableDictionary } from "@cascateer/lib";
|
|
1
2
|
import { constant, Dictionary, mapValues, tap, thru } from "lodash";
|
|
2
3
|
import {
|
|
3
4
|
identity,
|
|
@@ -8,8 +9,6 @@ import {
|
|
|
8
9
|
shareReplay,
|
|
9
10
|
UnaryFunction,
|
|
10
11
|
} from "rxjs";
|
|
11
|
-
import { ExtendableDictionary } from "./lib";
|
|
12
|
-
import { ComputedSignal, Signal } from "./observable";
|
|
13
12
|
import {
|
|
14
13
|
flatMap,
|
|
15
14
|
MulticastAction,
|
|
@@ -17,7 +16,8 @@ import {
|
|
|
17
16
|
sequence,
|
|
18
17
|
} from "./operators";
|
|
19
18
|
import { Serializable } from "./serializable";
|
|
20
|
-
import {
|
|
19
|
+
import { ComputedSignal, Signal } from "./signal";
|
|
20
|
+
import { Action } from "./types";
|
|
21
21
|
|
|
22
22
|
export type StoreEffect<Result> = () => Signal<Result>;
|
|
23
23
|
|
|
@@ -70,7 +70,7 @@ export class ExtendableStoreAdapter<
|
|
|
70
70
|
},
|
|
71
71
|
void
|
|
72
72
|
>;
|
|
73
|
-
register: UnaryFunction<(args: any) =>
|
|
73
|
+
register: UnaryFunction<(args: any) => EndoFunction<any>, void>;
|
|
74
74
|
}
|
|
75
75
|
>;
|
|
76
76
|
},
|
|
@@ -115,7 +115,7 @@ export class ExtendableStoreAdapter<
|
|
|
115
115
|
? T
|
|
116
116
|
: never,
|
|
117
117
|
>(
|
|
118
|
-
predicate: UnaryFunction<Args,
|
|
118
|
+
predicate: UnaryFunction<Args, EndoFunction<T>>,
|
|
119
119
|
config?: { sameOrigin?: boolean },
|
|
120
120
|
) => Action<Args, any>;
|
|
121
121
|
};
|
|
@@ -143,7 +143,7 @@ export class ExtendableStoreAdapter<
|
|
|
143
143
|
update: (predicate, config = {}) =>
|
|
144
144
|
thru(this.context.transform(key), (transform) => {
|
|
145
145
|
transform.register((args) =>
|
|
146
|
-
signal.
|
|
146
|
+
signal.pull(predicate(args)),
|
|
147
147
|
);
|
|
148
148
|
|
|
149
149
|
return (args) =>
|
package/src/terminal.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import { ExtendableDictionary } from "@cascateer/lib";
|
|
1
2
|
import { Dictionary } from "lodash";
|
|
2
3
|
import { UnaryFunction } from "rxjs";
|
|
3
4
|
import { ApiAdapter, ApiEffect } from "./api";
|
|
4
|
-
import {
|
|
5
|
-
import { ComputedSignal } from "./observable";
|
|
5
|
+
import { ComputedSignal } from "./signal";
|
|
6
6
|
import { asStoreEffects, StoreAdapter, StoreEffects } from "./store";
|
|
7
7
|
import {
|
|
8
8
|
Action,
|
package/src/types.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { Dictionary, mapValues, tap } from "lodash";
|
|
2
2
|
import { combineLatest, ReplaySubject, switchMap, UnaryFunction } from "rxjs";
|
|
3
3
|
import { Observable } from "rxjs/internal/Observable";
|
|
4
|
-
import {
|
|
5
|
-
import { memoizeHashed } from "./lib/memoizeHashed";
|
|
4
|
+
import { memoize } from "./lib/memoize";
|
|
6
5
|
import { ProxyObservable } from "./observable";
|
|
7
6
|
import { accumulate, every, some } from "./operators";
|
|
8
7
|
|
|
@@ -36,7 +35,7 @@ export class ProxyEffectInterceptor extends ReplaySubject<
|
|
|
36
35
|
effects: Effects,
|
|
37
36
|
): ProxyEffects<Effects> {
|
|
38
37
|
return mapValues(effects, (effect) =>
|
|
39
|
-
|
|
38
|
+
memoize((args) =>
|
|
40
39
|
tap(
|
|
41
40
|
new ProxyObservable(effect(args), (target, receiver) =>
|
|
42
41
|
combineLatest([target.pending, receiver.refCount]).pipe(every()),
|
|
@@ -65,15 +64,3 @@ export interface Action<Args, Result> extends UnaryFunction<
|
|
|
65
64
|
Args,
|
|
66
65
|
Promise<Result>
|
|
67
66
|
> {}
|
|
68
|
-
|
|
69
|
-
export type MaybeArray<T> = T | T[];
|
|
70
|
-
|
|
71
|
-
export type MaybeObservable<T> = T | Observable<T>;
|
|
72
|
-
|
|
73
|
-
export type MaybeObservableInput<T> = T | ObservableInput<T>;
|
|
74
|
-
|
|
75
|
-
export type MaybeObservableInputTuple<T> = {
|
|
76
|
-
[K in keyof T]: MaybeObservableInput<T[K]>;
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
export type Transform<T> = UnaryFunction<T, T>;
|
package/src/lib/Enumerable.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
export class Enumerable<T> extends Array<
|
|
2
|
-
T extends readonly (infer Index)[] ? Index : never
|
|
3
|
-
> {
|
|
4
|
-
constructor(value: T) {
|
|
5
|
-
super();
|
|
6
|
-
|
|
7
|
-
this.push(...(Array.isArray(value) ? value : []));
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export type EnumerableItem<
|
|
12
|
-
T,
|
|
13
|
-
Index extends number = number,
|
|
14
|
-
> = Enumerable<T>[Index];
|
|
15
|
-
|
|
16
|
-
export interface Enumerator<T> {
|
|
17
|
-
<Index extends number>(
|
|
18
|
-
item: EnumerableItem<T, Index>,
|
|
19
|
-
index: Index,
|
|
20
|
-
): PropertyKey;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export const asEnumerable = <T>(value: T) => new Enumerable<T>(value);
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { Dictionary, once } from "lodash";
|
|
2
|
-
import { AsyncSubject, lastValueFrom, UnaryFunction } from "rxjs";
|
|
3
|
-
import { keys } from "./keys";
|
|
4
|
-
|
|
5
|
-
export type Extend<T, U> = Omit<T, keyof U> & U;
|
|
6
|
-
|
|
7
|
-
export class ExtendableDictionary<T, U extends Dictionary<T>> {
|
|
8
|
-
constructor(
|
|
9
|
-
public currentValue: U,
|
|
10
|
-
private value = new AsyncSubject<Dictionary<T>>(),
|
|
11
|
-
) {}
|
|
12
|
-
|
|
13
|
-
complete = once((): U => {
|
|
14
|
-
this.value.next(this.currentValue);
|
|
15
|
-
this.value.complete();
|
|
16
|
-
|
|
17
|
-
return this.currentValue;
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
extend<V extends Dictionary<T>>(
|
|
21
|
-
value: (
|
|
22
|
-
currentValue: U,
|
|
23
|
-
) => ({
|
|
24
|
-
property,
|
|
25
|
-
}: {
|
|
26
|
-
property: (constructor: UnaryFunction<Promise<string>, T>) => T;
|
|
27
|
-
}) => V,
|
|
28
|
-
) {
|
|
29
|
-
return new ExtendableDictionary<T, Extend<U, V>>(
|
|
30
|
-
{
|
|
31
|
-
...this.currentValue,
|
|
32
|
-
...value(this.currentValue)({
|
|
33
|
-
property: (constructor) => {
|
|
34
|
-
const property = constructor(
|
|
35
|
-
lastValueFrom(this.value).then(
|
|
36
|
-
(value) =>
|
|
37
|
-
new Promise<string>((resolve, reject) => {
|
|
38
|
-
for (const key of keys(value)) {
|
|
39
|
-
if (value[key] === property) {
|
|
40
|
-
return resolve(key);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
reject();
|
|
45
|
-
}),
|
|
46
|
-
),
|
|
47
|
-
);
|
|
48
|
-
|
|
49
|
-
return property;
|
|
50
|
-
},
|
|
51
|
-
}),
|
|
52
|
-
},
|
|
53
|
-
this.value,
|
|
54
|
-
);
|
|
55
|
-
}
|
|
56
|
-
}
|
package/src/lib/chunkWith.ts
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { Comparator, uniqWith } from "lodash";
|
|
2
|
-
|
|
3
|
-
export const chunkWith = <T>(
|
|
4
|
-
actions: T[],
|
|
5
|
-
comparator?: Comparator<T>,
|
|
6
|
-
): T[][] => [
|
|
7
|
-
...{
|
|
8
|
-
*[Symbol.iterator]() {
|
|
9
|
-
const prevActions = new Array<T>();
|
|
10
|
-
|
|
11
|
-
if (actions.length == 0) {
|
|
12
|
-
return;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
for (const action of actions) {
|
|
16
|
-
if (uniqWith([...prevActions, action], comparator).length === 1) {
|
|
17
|
-
prevActions.push(action);
|
|
18
|
-
} else {
|
|
19
|
-
yield prevActions.splice(0, prevActions.length, action);
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
yield prevActions;
|
|
24
|
-
},
|
|
25
|
-
},
|
|
26
|
-
];
|
package/src/lib/index.ts
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { Observable, of } from "rxjs";
|
|
2
|
-
import { isObservable } from "rxjs/internal/util/isObservable";
|
|
3
|
-
import { MaybeArray, MaybeObservable } from "../types";
|
|
4
|
-
|
|
5
|
-
export { chunkWith } from "./chunkWith";
|
|
6
|
-
export {
|
|
7
|
-
asEnumerable,
|
|
8
|
-
type Enumerable,
|
|
9
|
-
type EnumerableItem,
|
|
10
|
-
type Enumerator,
|
|
11
|
-
} from "./Enumerable";
|
|
12
|
-
export { ExtendableDictionary } from "./ExtendableDictionary";
|
|
13
|
-
export { keys } from "./keys";
|
|
14
|
-
export { nthArg } from "./nthArg";
|
|
15
|
-
export { property } from "./property";
|
|
16
|
-
|
|
17
|
-
export const asArray = <T>(array: MaybeArray<T>): Array<T> =>
|
|
18
|
-
Array.isArray(array) ? array : [array];
|
|
19
|
-
|
|
20
|
-
export const asObservable = <T>(value: MaybeObservable<T>): Observable<T> =>
|
|
21
|
-
isObservable(value) ? value : of(value);
|
|
22
|
-
|
|
23
|
-
export const nonNullable = <T>(value: T): NonNullable<T> => {
|
|
24
|
-
if (value == null) {
|
|
25
|
-
throw new Error(`${value} is nil`);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
return value;
|
|
29
|
-
};
|
package/src/lib/keys.ts
DELETED
package/src/lib/memoizeHashed.ts
DELETED
package/src/lib/nthArg.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
export function nthArg<T>(n: 0): (arg0: T) => T;
|
|
2
|
-
export function nthArg<T>(n: 1): (arg0: any, arg1: T) => T;
|
|
3
|
-
export function nthArg<T>(n: 2): (arg0: any, arg1: any, arg2: T) => T;
|
|
4
|
-
export function nthArg<T>(n: number): (...args: any[]) => T {
|
|
5
|
-
return (...args) => args[n];
|
|
6
|
-
}
|
package/src/lib/property.ts
DELETED