Skip to content

Commit

Permalink
feat(rdom): add $subWithID(), add IDs for various constructs
Browse files Browse the repository at this point in the history
  • Loading branch information
postspectacular committed Apr 3, 2023
1 parent bfd4058 commit 404eacb
Show file tree
Hide file tree
Showing 9 changed files with 65 additions and 21 deletions.
3 changes: 3 additions & 0 deletions packages/rdom/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@
"./event": {
"default": "./event.js"
},
"./idgen": {
"default": "./idgen.js"
},
"./klist": {
"default": "./klist.js"
},
Expand Down
7 changes: 7 additions & 0 deletions packages/rdom/src/idgen.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type { ISubscribable } from "@thi.ng/rstream";

let NEXT_ID = 0;

/** @internal */
export const __nextID = (name: string, src?: ISubscribable<any>) =>
src ? `rdom$${name}-${src.id}-${NEXT_ID++}` : `rdom$${name}-${NEXT_ID++}`;
1 change: 1 addition & 0 deletions packages/rdom/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export * from "./compile.js";
export * from "./component.js";
export * from "./dom.js";
export * from "./event.js";
export * from "./idgen.js";
export * from "./klist.js";
export * from "./list.js";
export * from "./object.js";
Expand Down
13 changes: 6 additions & 7 deletions packages/rdom/src/klist.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import type { Fn, Fn2, NumOrString } from "@thi.ng/api";
import type { ISubscribable } from "@thi.ng/rstream";
import { __nextID } from "@thi.ng/rstream/idgen";
import type { IComponent, IMountWithState, NumOrElement } from "./api.js";
import { $compile } from "./compile.js";
import { Component } from "./component.js";
import { $moveTo } from "./dom.js";
import { $Sub } from "./sub.js";
import { __nextID } from "./idgen.js";
import { $subWithID } from "./sub.js";

interface KListItem {
k: NumOrString;
Expand Down Expand Up @@ -71,11 +71,10 @@ export const $klist = <T>(
childCtor: Fn<T, any>,
keyFn?: Fn2<T, number, NumOrString>
) =>
src.subscribe(
new $Sub<T[]>(
new KList<T>(tag, attribs, childCtor, keyFn),
`rdom$klist-${src.id}-${__nextID()}`
)
$subWithID(
src,
new KList<T>(tag, attribs, childCtor, keyFn),
__nextID("klist", src)
);

export class KList<T> extends Component<T[]> implements IMountWithState<T[]> {
Expand Down
13 changes: 6 additions & 7 deletions packages/rdom/src/list.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import type { Fn, Predicate2 } from "@thi.ng/api";
import type { ISubscribable } from "@thi.ng/rstream";
import { __nextID } from "@thi.ng/rstream/idgen";
import type { IComponent, IMountWithState, NumOrElement } from "./api.js";
import { $compile } from "./compile.js";
import { Component } from "./component.js";
import { $Sub } from "./sub.js";
import { __nextID } from "./idgen.js";
import { $subWithID } from "./sub.js";

/**
* Creates a generalized and dynamically updating list component from items of
Expand Down Expand Up @@ -60,11 +60,10 @@ export const $list = <T>(
ctor: Fn<T, any>,
equiv?: Predicate2<T>
) =>
src.subscribe(
new $Sub<T[]>(
new List<T>(tag, attribs, ctor, equiv),
`rdom$list-${src.id}-${__nextID()}`
)
$subWithID(
src,
new List<T>(tag, attribs, ctor, equiv),
__nextID("list", src)
);

export class List<T> extends Component implements IMountWithState<T[]> {
Expand Down
10 changes: 8 additions & 2 deletions packages/rdom/src/object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import type {
NumOrElement,
} from "./api.js";
import { Component } from "./component.js";
import { $sub } from "./sub.js";
import { __nextID } from "./idgen.js";
import { $subWithID } from "./sub.js";

/**
* Creates a control component wrapper with an internal stream setup for user
Expand Down Expand Up @@ -91,7 +92,12 @@ export const $subObject = <T extends object, K extends Keys<T>>(
src: ISubscribable<T>,
opts: Partial<StreamObjOpts<T, K>>,
inner: Fn<StreamObj<T, K>["streams"], Promise<ComponentLike>>
) => $sub<T>(src, $object(src.deref() || <any>{}, opts, inner));
) =>
$subWithID<T>(
src,
$object(src.deref() || <any>{}, opts, inner),
__nextID("obj", src)
);

export class $Object<T extends object, K extends Keys<T>>
extends Component
Expand Down
5 changes: 3 additions & 2 deletions packages/rdom/src/replace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import type { ISubscribable } from "@thi.ng/rstream";
import type { IComponent, IMountWithState, NumOrElement } from "./api.js";
import { $compile } from "./compile.js";
import { Component } from "./component.js";
import { $sub } from "./sub.js";
import { __nextID } from "./idgen.js";
import { $subWithID } from "./sub.js";
import { $wrapText } from "./wrap.js";

/**
Expand Down Expand Up @@ -38,7 +39,7 @@ import { $wrapText } from "./wrap.js";
* @param src -
*/
export const $replace = <T>(src: ISubscribable<T>) =>
$sub(src, new Replace<T>());
$subWithID(src, new Replace<T>(), __nextID("replace", src));

export class Replace<T> extends Component implements IMountWithState<T> {
protected parent?: Element;
Expand Down
15 changes: 15 additions & 0 deletions packages/rdom/src/sub.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,21 @@ export function $sub(
);
}

/**
* Version of {@link $sub} which supports specifying an rstream stream ID for
* the resulting subscription (useful for debugging/visualizing the reactive
* graph topology).
*
* @param src
* @param inner
* @param id
*/
export const $subWithID = <T>(
src: ISubscribable<T>,
inner: IMountWithState<T>,
id: string
): IComponent<T> => <$Sub>src.subscribe(new $Sub(inner, id));

export class $Sub<T = any> extends Subscription<T, T> {
el?: Element;

Expand Down
19 changes: 16 additions & 3 deletions packages/rdom/src/switch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import type { ISubscribable } from "@thi.ng/rstream";
import type { IComponent, IMountWithState, NumOrElement } from "./api.js";
import { $compile } from "./compile.js";
import { Component } from "./component.js";
import { $sub } from "./sub.js";
import { __nextID } from "./idgen.js";
import { $subWithID } from "./sub.js";
import { $wrapText } from "./wrap.js";

/**
Expand Down Expand Up @@ -65,7 +66,12 @@ export const $switch = <T>(
ctors: Record<NumOrString, Fn<T, Promise<any>>>,
error?: Fn<Error, Promise<any>>,
loader?: Fn<T, Promise<any>>
) => $sub<T>(src, new Switch<T>(keyFn, ctors, error, loader));
) =>
$subWithID(
src,
new Switch<T>(keyFn, ctors, error, loader),
__nextID("switch", src)
);

/**
* Syntax sugar for {@link $switch} for cases when there's only a single
Expand All @@ -79,6 +85,8 @@ export const $switch = <T>(
* `$compile`d and then getting re-mounted. See {@link $switch} for
* further details.
*
* Also see {@link $replace}.
*
* @example
* ```ts
* $refresh(fromInterval(1000), async (x) => ["div", {}, x])
Expand All @@ -94,7 +102,12 @@ export const $refresh = <T>(
ctor: Fn<T, Promise<any>>,
error?: Fn<Error, Promise<any>>,
loader?: Fn<T, Promise<any>>
) => $switch(src, () => 0, { 0: ctor }, error, loader);
) =>
$subWithID(
src,
new Switch<T>(() => 0, { 0: ctor }, error, loader),
__nextID("refresh", src)
);

export class Switch<T> extends Component implements IMountWithState<T> {
protected val?: T;
Expand Down

0 comments on commit 404eacb

Please sign in to comment.