Skip to content

Commit

Permalink
Remove v1
Browse files Browse the repository at this point in the history
  • Loading branch information
dvtng committed Feb 4, 2025
1 parent 8a8fb31 commit dd7b995
Show file tree
Hide file tree
Showing 45 changed files with 145 additions and 745 deletions.
25 changes: 0 additions & 25 deletions cosmos/src/__tests__/derived-model.test.ts

This file was deleted.

59 changes: 15 additions & 44 deletions cosmos/src/__tests__/get-model.test.ts
Original file line number Diff line number Diff line change
@@ -1,50 +1,21 @@
import { expect, test, beforeEach } from "bun:test";
import { model } from "../model";
import { getModel } from "../get-model";
import { reset } from "../state";
import { Null } from "../null";

let count = 0;

const Counter = model({
type: "Counter",
refresh: { seconds: 60 },
async get() {
return ++count;
},
import { expect, test } from "bun:test";
import { model, getModel, request, compute } from "../index";
import { delay } from "./util/delay";

const Echo = model((value: string) => {
return request(async () => {
await delay(100);
return value;
});
});

beforeEach(() => {
count = 0;
reset(Counter());
const UppercaseEcho = model((value: string) => {
return compute((get) => {
return get(Echo(value)).value.toUpperCase();
});
});

test("getModel", async () => {
const [count] = await getModel(Counter());
expect(count).toBe(1);
});

test("getModel uses cached value", async () => {
await getModel(Counter());
const [count] = await getModel(Counter());
expect(count).toBe(1);
});

test("force model to update", async () => {
await getModel(Counter());
reset(Counter());
const [count] = await getModel(Counter());
expect(count).toBe(2);
});

test("get null model", async () => {
const enabled = false;
const [value] = await getModel(enabled ? Counter() : Null());
expect(value).toBe(null);
});

test("get expiry", async () => {
const now = Date.now();
const [_, { expiry }] = await getModel(Counter());
expect(expiry).toBe(now + 60 * 1000);
const uppercaseEcho = await getModel(UppercaseEcho("test"));
expect(uppercaseEcho.value).toBe("TEST");
});
File renamed without changes.
File renamed without changes.
49 changes: 0 additions & 49 deletions cosmos/src/core-types.ts

This file was deleted.

2 changes: 1 addition & 1 deletion cosmos/src/v2/core.ts → cosmos/src/core.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Duration } from "../duration";
import type { Duration } from "./duration";
import type { Ready } from "./later";
import type { Mapper } from "./later-map";

Expand Down
4 changes: 2 additions & 2 deletions cosmos/src/v2/cosmos.ts → cosmos/src/cosmos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import { proxy, subscribe, ref } from "valtio";
import { type Space, type Meta, type Spec, type State } from "./core";
import { serializeArgs } from "./serialize-args";
import { getNextSubscriberId } from "./get-next-subscriber-id";
import { toMs } from "../duration";
import { toMs } from "./duration";
import { type Ready } from "./later";
import { createMapper } from "./later-map";
import { setSmartTimeout } from "../set-smart-timeout";
import { setSmartTimeout } from "./set-smart-timeout";

const KEEP_ALIVE_MS = 1000;

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
37 changes: 28 additions & 9 deletions cosmos/src/get-model.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,30 @@
import type { ModelResult, Query, QueryType } from "./core-types";
import { getAtom, getPromise } from "./state";
import type { Spec, State } from "./core";
import { getPromise, initSpace } from "./cosmos";
import type { Ready } from "./later";

/**
* Resolve a model query as a promise.
*/
export function getModel<Q extends Query>(query: Q) {
return getPromise(query).then((atom) => {
return [atom.value, atom, query] as ModelResult<QueryType<Q>>;
});
export type GetModelResult<T> = State<T> & PromiseShape<State<Ready<T>>>;

type PromiseShape<T> = {
then: Promise<T>["then"];
catch: Promise<T>["catch"];
finally: Promise<T>["finally"];
};

export function getModel<T>(spec: Spec<T>): GetModelResult<T> {
const space = initSpace(spec);
return {
...space.state,
get then() {
const promise = getPromise(spec);
return promise.then.bind(promise);
},
get catch() {
const promise = getPromise(spec);
return promise.catch.bind(promise);
},
get finally() {
const promise = getPromise(spec);
return promise.finally.bind(promise);
},
};
}
File renamed without changes.
11 changes: 8 additions & 3 deletions cosmos/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
export * from "./later";
export * from "./core";
export * from "./model";
export * from "./use-model";
export * from "./set-model";
export * from "./get-model";
export * from "./null";
export * from "./wait-for";
export { getAtom, checkAtom } from "./state";
export * from "./snapshot";
export * from "./value";
export * from "./compute";
export * from "./request";
export * from "./persist";
File renamed without changes.
File renamed without changes.
79 changes: 47 additions & 32 deletions cosmos/src/model.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,54 @@
import stableStringify from "safe-stable-stringify";
import type { Query } from "./core-types";
import type { GetterModel } from "./templates/getter-model";
import { fromGetterModel, isGetterModel } from "./templates/getter-model";
import type { DerivedModel } from "./templates/derived-model";
import { fromDerivedModel, isDerivedModel } from "./templates/derived-model";
import {
fromEmitterModel,
isEmitterModel,
type EmitterModel,
} from "./templates/emitter-model";

export function model<T, P extends object | void = void>(
m: GetterModel<T, P> | EmitterModel<T, P> | DerivedModel<T, P>
) {
// TODO make it easier to add new model templates
const genericModel = isGetterModel<T, P>(m)
? fromGetterModel(m)
: isEmitterModel<T, P>(m)
? fromEmitterModel(m)
: isDerivedModel<T, P>(m)
? fromDerivedModel(m)
: (null as never);

return function buildQuery(params: P): Query<T, P> {
import type { Behavior, Model } from "./core";
import { combineBehavior, type Traits } from "./combine-behavior";

export function model<A extends any[], V>(resolve: Resolve<A, V>): Model<A, V>;

export function model<A extends any[], V>(
identity: string | Identity<A>,
resolve: Resolve<A, V>
): Model<A, V>;

export function model<A extends any[], V>(
identity: string | Identity<A> | Resolve<A, V>,
resolve?: Resolve<A, V>
): Model<A, V> {
// Create a default identity if one is not provided
if (typeof identity === "function") {
return model(toIdentity({}), identity);
}

const _identity = toIdentity(identity);
const _resolve = resolve!;

return (...args) => {
return {
$key: `${genericModel.type}(${serializeParams(params)})`,
model: genericModel,
params,
name: _identity.name,
args: _identity.args(...args),
resolve: () => combineBehavior(_resolve(...args)),
};
};
}

function serializeParams<P extends object | void>(params: P) {
if (params == null) {
return "";
type Identity<A extends any[]> = {
name: string;
args: (...args: A) => unknown[];
};

type Resolve<A extends any[], V> = (...args: A) => Behavior<V> | Traits<V>;

let nextModelId = 0;

function toIdentity<A extends any[]>(
identity: string | Partial<Identity<A>>
): Identity<A> {
if (typeof identity === "string") {
return {
name: identity,
args: (...args) => args,
};
}
return stableStringify(params);
return {
name: identity.name ?? `MODEL-${nextModelId++}`,
args: identity.args ?? ((...args) => args),
};
}
8 changes: 0 additions & 8 deletions cosmos/src/null.ts

This file was deleted.

File renamed without changes.
2 changes: 1 addition & 1 deletion cosmos/src/v2/request.ts → cosmos/src/request.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { type Duration } from "../duration";
import { type Duration } from "./duration";
import { asError, loading, type Later } from "./later";
import type { Behavior } from "./core";
import { Timer } from "./timer";
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit dd7b995

Please sign in to comment.