Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some long-needed renaming and consolidation (#90)Co-authored-by: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> #90

Merged
merged 47 commits into from
Apr 14, 2023
Merged
Changes from 1 commit
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
4b73e86
Some long-needed renaming
wycats Mar 23, 2023
9fc23ba
Rename "internal" concepts to Tag and Tagged
wycats Mar 23, 2023
8287abe
Created `@starbeam/tags`
wycats Mar 23, 2023
c24194c
WIP
wycats Mar 23, 2023
ff95ee1
WIP
wycats Mar 24, 2023
0f07706
Consolidate and simplify the core types
wycats Mar 24, 2023
c0dc1b3
Start defining @starbeam/reactive
wycats Mar 24, 2023
36cda9e
Extract Cell into `reactive`
wycats Mar 25, 2023
5430b06
Rename timeline to runtime
wycats Mar 26, 2023
63f49e0
Fix tests
wycats Mar 26, 2023
88cdd57
WIP: Migrating to new runtime
wycats Mar 26, 2023
7097a55
More conceptual cleanup plus foundational docs
wycats Mar 27, 2023
dba6a21
Add a hand-crafted resource test
wycats Mar 28, 2023
276cba3
WIP
wycats Mar 28, 2023
92c4573
Third time's the charm!
wycats Mar 30, 2023
24b0453
WIP @starbeam/resource
wycats Mar 31, 2023
9665534
WIP
wycats Mar 31, 2023
21be030
Document `@starbeam/resource` + codebase GC
wycats Apr 3, 2023
3d83192
@starbeam/service
wycats Apr 3, 2023
b03faba
Continue cleaning up resources
wycats Apr 3, 2023
19c10bd
Added support for use(() => Blueprint)
wycats Apr 3, 2023
f7efabb
Update to pnpm 8
NullVoxPopuli Mar 29, 2023
2464de5
Forgot the first occuranec
NullVoxPopuli Mar 29, 2023
dcca995
Pin pnpm in volta
NullVoxPopuli Apr 4, 2023
f9f17f3
React tests pass
wycats Apr 4, 2023
fb52ba8
Preact tests pass!
wycats Apr 4, 2023
142416b
Massive cleanup
wycats Apr 7, 2023
fcdd2a9
Cleaned up @starbeam/reactive
wycats Apr 7, 2023
2d53269
Start cleaning up runtime
wycats Apr 7, 2023
0cee00f
Streamling subscriptions
wycats Apr 7, 2023
f032421
Clean up usage of changed APIs
wycats Apr 7, 2023
41f6092
React cleanup
wycats Apr 10, 2023
af86b08
Finish useStrictLifecycle Cleanup
wycats Apr 10, 2023
30215b2
React cleanup
wycats Apr 10, 2023
68ae89a
Fix resource exports
wycats Apr 10, 2023
01cb2e9
Merge remote-tracking branch 'nullvox/update-ci' into feature/primiti…
wycats Apr 13, 2023
c0ea070
Fixes jsnation smoke test
wycats Apr 13, 2023
6325c4e
Avoid "no test suite" CI fail
wycats Apr 13, 2023
127b2a0
Fix typecheck
wycats Apr 13, 2023
75cf20d
Fix ci:types
wycats Apr 13, 2023
ca8a5e3
Fix lints
wycats Apr 13, 2023
e77a419
Re-fix ci:types
wycats Apr 13, 2023
fa0a112
Fix FIXME: renderer unsubscriptions
wycats Apr 13, 2023
f647b5f
Re-fix ci:lint
wycats Apr 13, 2023
048d5b8
More ci:lint fixes
wycats Apr 13, 2023
9312386
More ci:fix
wycats Apr 13, 2023
a166a88
more ci:lint fixes
wycats Apr 13, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Consolidate and simplify the core types
Also consolidate and simplify the functions for interacting with them
wycats committed Mar 24, 2023
commit 0f07706d8cbb6866df2e6ef60fea4791d39edfac
4 changes: 2 additions & 2 deletions packages/preact/preact/src/options.ts
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ import type {
InternalElement,
} from "@starbeam/preact-utils";
import { Plugin } from "@starbeam/preact-utils";
import { CONTEXT, LIFETIME, Reactive } from "@starbeam/timeline";
import { CONTEXT, isReactive, LIFETIME } from "@starbeam/timeline";
import type { ComponentType } from "preact";

import { ComponentFrame } from "./frame.js";
@@ -22,7 +22,7 @@ export const setup = Plugin((on) => {

on.vnode((vnode) => {
vnode.processChildren((child) => {
if (Reactive.is(child)) {
if (isReactive(child)) {
return String(child.read());
} else {
return child;
6 changes: 4 additions & 2 deletions packages/react/react/src/use-setup.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { callerStack, Desc } from "@starbeam/debug";
import type { Description } from "@starbeam/interfaces";
import { PolledFormula, Reactive } from "@starbeam/universal";
import { isReactive } from "@starbeam/timeline";
import type { Reactive } from "@starbeam/universal";
import { PolledFormula } from "@starbeam/universal";
import {
setupFunction,
unsafeTrackedElsewhere,
@@ -73,7 +75,7 @@ export function useSetup<

let currentProps: unknown = undefined;

if (Reactive.is(instance)) {
if (isReactive(instance)) {
ReactiveElement.subscribe(element, instance);
return { element, instance: { type: "reactive", value: instance } };
} else if (typeof instance === "function") {
4 changes: 2 additions & 2 deletions packages/react/react/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { type Description, Desc } from "@starbeam/debug";
import { Desc, type Description } from "@starbeam/debug";
import type { Reactive } from "@starbeam/interfaces";
import { UNINITIALIZED } from "@starbeam/shared";
import type { Reactive } from "@starbeam/timeline";
import { Cell } from "@starbeam/universal";
import { useRef } from "react";

9 changes: 5 additions & 4 deletions packages/react/react/tests/use-resource.spec.ts
Original file line number Diff line number Diff line change
@@ -3,12 +3,13 @@
import { entryPoint } from "@starbeam/debug";
import reactive from "@starbeam/js";
import { use, useProp, useReactive, useSetup } from "@starbeam/react";
import { Reactive } from "@starbeam/timeline";
import { intoReactive } from "@starbeam/timeline";
import {
type ResourceBlueprint,
Cell,
Formula,
type IntoReactive,
Resource,
type ResourceBlueprint,
} from "@starbeam/universal";
import { html, react, testReact } from "@starbeam-workspace/react-test-utils";
import { beforeEach, describe, expect } from "vitest";
@@ -420,9 +421,9 @@ function send(message: string): void {
}

function ChannelResource(
name: Reactive<string> | string
name: IntoReactive<string>
): ResourceBlueprint<string | undefined> {
const reactive = Reactive.from(name);
const reactive = intoReactive(name);

return Resource((r) => {
const lastMessage = Cell<string | undefined>(undefined, "last message");
2 changes: 1 addition & 1 deletion packages/universal/interfaces/src/protocol.d.ts
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@ export interface AbstractTag {
readonly description: Description;
}

export type List<T> = Iterable<T> | readonly T[];
export type List<T> = Iterable<T>;

export class TagMethods {
readonly id: ReactiveId;
13 changes: 8 additions & 5 deletions packages/universal/timeline/index.ts
Original file line number Diff line number Diff line change
@@ -21,11 +21,14 @@ export {
Subscriptions,
} from "./src/timeline/subscriptions.js";
export { diff } from "./src/timeline/utils.js";
export { Reactive } from "./src/utils/utils.js";
export {
intoReactive,
isReactive,
read,
Static,
} from "./src/utils/reactive.js";
export type { Tag, Tagged } from "@starbeam/interfaces";
export { TAG } from "@starbeam/shared";

import type * as interfaces from "@starbeam/interfaces";
export type { interfaces };

export { getTag, Timestamp } from "@starbeam/tags";
export type { interfaces };
import type * as interfaces from "@starbeam/interfaces";
63 changes: 44 additions & 19 deletions packages/universal/timeline/src/utils/reactive.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type * as Debug from "@starbeam/debug";
import { Desc } from "@starbeam/debug";
import { callerStack, Desc } from "@starbeam/debug";
import type * as interfaces from "@starbeam/interfaces";
import { TAG } from "@starbeam/shared";
import { StaticTag } from "@starbeam/tags";
@@ -17,33 +17,55 @@ function is<T>(
);
}

export const Reactive = {
is<T>(this: void, value: unknown): value is interfaces.Reactive<T> {
return is(value) && hasRead(value);
},
export function isReactive<T>(
this: void,
value: unknown
): value is Reactive<T> {
return is(value) && hasRead(value);
}

from<T>(
this: void,
value: T | Reactive<T>,
description?: string | Debug.Description
): Reactive<T> {
if (Reactive.is(value)) {
return value;
} else {
return new Static(value, Desc("static", description));
}
},
};
export function read<T>(
this: void,
value: T | Reactive<T>,
caller = callerStack()
): T {
if (is(value) && hasRead(value)) {
return value.read(caller);
} else {
return value;
}
}

export function intoReactive<T>(
this: void,
value: T | Reactive<T>,
description?: string | Debug.Description
): Reactive<T> {
if (isReactive(value)) {
return value;
} else {
return Static(value, Desc("static", description));
}
}

function hasRead<T>(value: object): value is { read: () => T } {
return "read" in value && typeof value.read === "function";
}

class Static<T> implements interfaces.ReactiveValue<T, interfaces.StaticTag> {
export class StaticImpl<T>
implements interfaces.ReactiveValue<T, interfaces.StaticTag>
{
static create = <T>(
value: T,
description?: string | Debug.Description
): StaticImpl<T> => {
return new StaticImpl(value, Desc("static", description));
};

readonly #value: T;
readonly [TAG]: interfaces.StaticTag;

constructor(value: T, description: Debug.Description) {
private constructor(value: T, description: Debug.Description) {
this.#value = value;
this[TAG] = StaticTag.create(description);
}
@@ -56,3 +78,6 @@ class Static<T> implements interfaces.ReactiveValue<T, interfaces.StaticTag> {
return this.#value;
}
}

export const Static = StaticImpl.create;
export type Static<T> = StaticImpl<T>;
1 change: 0 additions & 1 deletion packages/universal/timeline/src/utils/utils.ts

This file was deleted.

1 change: 0 additions & 1 deletion packages/universal/universal/index.ts
Original file line number Diff line number Diff line change
@@ -48,7 +48,6 @@ export {
service,
type ServiceBlueprint,
} from "./src/reactive-core/service.js";
export { Static } from "./src/reactive-core/static.js";
export {
type Variant,
type VariantEntry,
9 changes: 5 additions & 4 deletions packages/universal/universal/src/reactive-core/into.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import type { Description } from "@starbeam/debug";
import { Desc } from "@starbeam/debug";
import { intoReactive, isReactive } from "@starbeam/timeline";

import type { ReactiveBlueprint } from "./reactive.js";
import { type Blueprint, type ReactiveFactory, Reactive } from "./reactive.js";
import { type Blueprint, Reactive, type ReactiveFactory } from "./reactive.js";
import { ResourceBlueprint } from "./resource/resource.js";
import { type ResourceFactory, Resource } from "./resource/resource.js";
import { Resource, type ResourceFactory } from "./resource/resource.js";

export type IntoResource<T, Initial extends undefined = undefined> =
| ResourceBlueprint<T, Initial>
@@ -50,7 +51,7 @@ function resource<T>(
description?: Description | string
): Reactive<T> {
const desc = Desc("resource", description);
return Reactive.from(
return intoReactive(
IntoResource(create as IntoResource<unknown>, desc).create(owner)
) as Reactive<T>;
}
@@ -65,7 +66,7 @@ function createReactiveObject<T extends Reactive<unknown>>(create: T): T;
function createReactiveObject(
create: IntoReactiveObject<unknown> | Reactive<unknown>
): unknown {
if (Reactive.is(create)) {
if (isReactive(create)) {
return create;
} else {
return IntoReactiveObject(create).create();
24 changes: 5 additions & 19 deletions packages/universal/universal/src/reactive-core/reactive.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Desc, type Description } from "@starbeam/debug";
import type { ReactiveValue,Tag } from "@starbeam/interfaces";
import { Reactive as TimelineReactive } from "@starbeam/timeline";
import type { ReactiveValue, Tag } from "@starbeam/interfaces";
import type * as interfaces from "@starbeam/interfaces";
import { isObject } from "@starbeam/verify";

import type { ResourceBlueprint } from "./resource/resource.js";
@@ -19,25 +19,11 @@ export function Reactive<T>(
return new ReactiveBlueprint(constructor, desc);
}

Reactive.is = TimelineReactive.is;
Reactive.from = TimelineReactive.from;
export type IntoReactive<T> = interfaces.Reactive<T> | T;

Reactive.read = <T>(value: IntoReactive<T>): T => {
if (Reactive.is(value)) {
return value.current;
} else {
return value;
}
};

export type IntoReactive<T> = Reactive<T> | T;

export type TypedReactive<
T,
I extends Tag = Tag
> = ReactiveValue<T, I>;
export type TypedReactive<T, I extends Tag = Tag> = ReactiveValue<T, I>;

export type Reactive<T> = TimelineReactive<T>;
export type Reactive<T> = interfaces.Reactive<T>;

export class ReactiveBlueprint<T> {
static is<T>(value: T | ReactiveBlueprint<T>): value is ReactiveBlueprint<T> {
Original file line number Diff line number Diff line change
@@ -14,15 +14,14 @@
*/

import { Desc, type Description } from "@starbeam/debug";
import type { Reactive } from "@starbeam/interfaces";
import { UNINITIALIZED } from "@starbeam/shared";
import type { Reactive } from "@starbeam/timeline";
import { LIFETIME } from "@starbeam/timeline";
import { LIFETIME, Static } from "@starbeam/timeline";
import { isWeakKey } from "@starbeam/verify";

import { Formula } from "../formula/formula.js";
import type { IntoResource } from "../into.js";
import { type Blueprint, ReactiveBlueprint } from "../reactive.js";
import { Static } from "../static.js";
import type { ResourceRun } from "./run.js";
import { ResourceState } from "./state.js";

12 changes: 7 additions & 5 deletions packages/universal/universal/src/reactive-core/resource/state.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { Description } from "@starbeam/debug";
import type { Reactive } from "@starbeam/interfaces";
import { UNINITIALIZED } from "@starbeam/shared";
import { LIFETIME, Reactive } from "@starbeam/timeline";
import { isReactive, LIFETIME, Static } from "@starbeam/timeline";

import { Formula } from "../formula/formula.js";
import { Static } from "../static.js";
import {
type AssimilatedResourceReturn,
brandResource,
@@ -164,17 +164,19 @@ export class ResourceState<T> {
if (isResource(resource)) {
LIFETIME.link(nextRun, resource, { root: this.#owner });
return resource as AssimilatedResourceReturn<R>;
} else if (Reactive.is(resource)) {
} else if (isReactive(resource)) {
return resource as AssimilatedResourceReturn<R>;
} else if (resource instanceof ResourceBlueprint) {
return resource.use(nextRun, this) as AssimilatedResourceReturn<R>;
} else if (resource === UNINITIALIZED) {
return Static(undefined) as AssimilatedResourceReturn<R>;
return Static(
undefined
) as Reactive<undefined> as AssimilatedResourceReturn<R>;
} else {
return Static(
resource,
desc.detail("return")
) as AssimilatedResourceReturn<R>;
) as Reactive<undefined> as AssimilatedResourceReturn<R>;
}
}
}
2 changes: 1 addition & 1 deletion packages/universal/universal/src/reactive-core/service.ts
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ import { Desc } from "@starbeam/debug";
import type { Description, Reactive } from "@starbeam/interfaces";
import { CONTEXT } from "@starbeam/timeline";

import { type IntoResource, Factory } from "./into.js";
import { Factory, type IntoResource } from "./into.js";
import type { Blueprint } from "./reactive.js";
import type { ResourceFactory } from "./resource/resource.js";

16 changes: 0 additions & 16 deletions packages/universal/universal/src/reactive-core/static.ts

This file was deleted.

13 changes: 7 additions & 6 deletions packages/universal/universal/tests/custom.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { CustomBlueprint } from "@starbeam/universal";
import { type IntoReactive, Reactive } from "@starbeam/universal";
import { intoReactive, read } from "@starbeam/timeline";
import type { CustomBlueprint, Reactive } from "@starbeam/universal";
import { type IntoReactive } from "@starbeam/universal";
import { Cell, Custom, Formula } from "@starbeam/universal";
import { describe, expect, test } from "vitest";

@@ -43,15 +44,15 @@ describe("Custom reactive objects", () => {
return Custom(() => {
const formatter = Formula(
() =>
new Intl.DateTimeFormat(Reactive.read(locale), {
new Intl.DateTimeFormat(read(locale), {
year: "numeric",
month: "long",
day: "numeric",
})
);

return Formula(() => {
return formatter().format(Reactive.read(date));
return formatter().format(read(date));
});
});
}
@@ -77,7 +78,7 @@ describe("Custom reactive objects", () => {
return Custom(() => {
const age = Cell(0);
return {
name: Reactive.from(name),
name: intoReactive(name),

get age() {
return age.current;
@@ -152,7 +153,7 @@ class GenericImpl<S extends string> {
readonly #age = Cell(0);

constructor(name: IntoReactive<S>) {
this.#name = Reactive.from(name);
this.#name = intoReactive(name);
}

get name(): S {
4 changes: 2 additions & 2 deletions packages/universal/universal/tests/factory.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { entryPointFn } from "@starbeam/debug";
import { describeTagged } from "@starbeam/tags";
import { Frame } from "@starbeam/timeline";
import { Cell, FormulaValidation, Reactive, Static } from "@starbeam/universal";
import { Frame, Static } from "@starbeam/timeline";
import { Cell, FormulaValidation, Reactive } from "@starbeam/universal";
import { describe, expect, test } from "@starbeam-workspace/test-utils";

describe("reactive Factory", () => {
3 changes: 2 additions & 1 deletion packages/x/devtool/package.json
Original file line number Diff line number Diff line change
@@ -32,9 +32,10 @@
"@starbeam/core-utils": "workspace:^",
"@starbeam/debug": "workspace:^",
"@starbeam/interfaces": "workspace:^",
"@starbeam/tags": "workspace:^",
"@starbeam/timeline": "workspace:^",
"@starbeam/verify": "workspace:^",
"preact": "^10.11.3"
"preact": "^10.13.1"
},
"devDependencies": {
"@starbeam-dev/build-support": "workspace:*"
29 changes: 15 additions & 14 deletions packages/x/devtool/src/single/single-reactive.tsx
Original file line number Diff line number Diff line change
@@ -5,24 +5,26 @@ import type {
DebugOperation,
Description,
} from "@starbeam/debug";
import type { MutableInternals } from "@starbeam/interfaces";
import { ReactiveProtocol, TIMELINE } from "@starbeam/timeline";
import type { CellTag } from "@starbeam/interfaces";
import { getTag } from "@starbeam/tags";
import { taggedDescription } from "@starbeam/tags";
import { type Tagged, TIMELINE } from "@starbeam/timeline";
import { isPresent, verified } from "@starbeam/verify";
import { type JSX, render } from "preact";

export function DevtoolsFor(props: {
reactive: ReactiveProtocol;
reactive: Tagged;
log: DebugOperation[];
}): JSX.Element {
function computeDependencies(): Iterable<MutableInternals> {
return ReactiveProtocol.dependencies(props.reactive);
function computeDependencies(): Iterable<CellTag> {
return getTag(props.reactive).dependencies();
}

function computeInvalidated(): MutableInternals[] {
function computeInvalidated(): CellTag[] {
return props.log
.map((operation) => operation.for)
.filter(
(value): value is MutableInternals =>
(value): value is CellTag =>
value !== undefined && value.type === "cell"
);
}
@@ -38,7 +40,7 @@ export function DevtoolsFor(props: {
<li>
<span class="specified">description</span>
<span class="kind">
{ReactiveProtocol.description(props.reactive).fullName}
{taggedDescription(props.reactive).fullName}
</span>
</li>
<li>
@@ -102,7 +104,7 @@ function Dependency({
);
}

function unique(dependencies: MutableInternals[]): Description[] {
function unique(dependencies: CellTag[]): Description[] {
const descriptions = new Set(
dependencies.map((d) => d.description.userFacing)
);
@@ -111,25 +113,24 @@ function unique(dependencies: MutableInternals[]): Description[] {
}

export default function DevtoolsPane(
renderable: ReactiveProtocol,
renderable: Tagged,
log: DebugOperation[],
into: Element
): { update: (reactive: ReactiveProtocol, log: DebugOperation[]) => void } {
): { update: (reactive: Tagged, log: DebugOperation[]) => void } {
const app = <DevtoolsFor reactive={renderable} log={log} />;

render(app, into);

return {
update: (reactive: ReactiveProtocol, log: DebugOperation[]) => {
update: (reactive: Tagged, log: DebugOperation[]) => {
render(<DevtoolsFor reactive={reactive} log={log} />, into);
},
};
}

export function DevTools(
listener: DebugListener,

reactive: ReactiveProtocol
reactive: Tagged
): () => void {
const pane = DevtoolsPane(
reactive,
2 changes: 2 additions & 0 deletions pnpm-lock.yaml