Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
holic committed Jul 23, 2024
1 parent 3955ed2 commit cad0ffb
Showing 6 changed files with 93 additions and 24 deletions.
1 change: 1 addition & 0 deletions packages/store/ts/config/v2/namespaceWithShorthands.ts
Original file line number Diff line number Diff line change
@@ -48,6 +48,7 @@ export function resolveNamespaceWithShorthands<
...(tables ? { tables } : null),
};

// TODO: these should only be in `define...`?
validateNamespace(namespace, scope);
return resolveNamespace(namespace, scope) as never;
}
42 changes: 42 additions & 0 deletions packages/store/ts/config/v2/namespacesWithShorthands.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { show, flatMorph } from "@arktype/util";
import { isObject, mergeIfUndefined } from "./generics";
import { NamespacesInput } from "./input";
import { AbiTypeScope, Scope } from "./scope";
import { resolveNamespaceWithShorthands, validateNamespaceWithShorthands } from "./namespaceWithShorthands";

export type validateNamespacesWithShorthands<namespaces, scope extends Scope = AbiTypeScope> = {
[label in keyof namespaces]: validateNamespaceWithShorthands<namespaces[label], scope>;
};

export function validateNamespacesWithShorthands<scope extends Scope = AbiTypeScope>(
namespaces: unknown,
scope: scope,
): asserts namespaces is NamespacesInput {
if (!isObject(namespaces)) {
throw new Error(`Expected namespaces, received ${JSON.stringify(namespaces)}`);
}
for (const namespace of Object.values(namespaces)) {
validateNamespaceWithShorthands(namespace, scope);
}
}

export type resolveNamespacesWithShorthands<namespaces, scope extends Scope = AbiTypeScope> = {
readonly [label in keyof namespaces]: resolveNamespaceWithShorthands<
mergeIfUndefined<namespaces[label], { label: label }>,
scope
>;
};

export function resolveNamespacesWithShorthands<namespaces extends NamespacesInput, scope extends Scope = AbiTypeScope>(
namespaces: namespaces,
scope: scope,
): show<resolveNamespacesWithShorthands<namespaces, scope>> {
if (!isObject(namespaces)) {
throw new Error(`Expected namespaces config, received ${JSON.stringify(namespaces)}`);
}

return flatMorph(namespaces as NamespacesInput, (label, namespace) => [
label,
resolveNamespaceWithShorthands(mergeIfUndefined(namespace, { label }), scope),
]) as never;
}
6 changes: 3 additions & 3 deletions packages/store/ts/config/v2/store.ts
Original file line number Diff line number Diff line change
@@ -44,7 +44,7 @@ export function validateStore(input: unknown): asserts input is StoreInput {
}
}

type resolveStoreNamespaces<input> = "namespaces" extends keyof input
type resolveNamespaceMode<input> = "namespaces" extends keyof input
? {
readonly multipleNamespaces: true;
readonly namespace: undefined;
@@ -65,8 +65,8 @@ type resolveStoreNamespaces<input> = "namespaces" extends keyof input
>;
};

export type resolveStore<input> = resolveStoreNamespaces<input> & {
readonly tables: flattenNamespacedTables<resolveStoreNamespaces<input>>;
export type resolveStore<input> = resolveNamespaceMode<input> & {
readonly tables: flattenNamespacedTables<resolveNamespaceMode<input>>;
readonly sourceDirectory: "sourceDirectory" extends keyof input
? input["sourceDirectory"]
: CONFIG_DEFAULTS["sourceDirectory"];
4 changes: 4 additions & 0 deletions packages/store/ts/config/v2/storeWithShorthands.test.ts
Original file line number Diff line number Diff line change
@@ -38,6 +38,7 @@ describe("defineStoreWithShorthands", () => {
} as const;

const expectedConfig = {
multipleNamespaces: false,
...expectedBaseNamespace,
namespaces: {
"": {
@@ -102,6 +103,7 @@ describe("defineStoreWithShorthands", () => {
} as const;

const expectedConfig = {
multipleNamespaces: false,
...expectedBaseNamespace,
namespaces: {
"": {
@@ -156,6 +158,7 @@ describe("defineStoreWithShorthands", () => {
} as const;

const expectedConfig = {
multipleNamespaces: false,
...expectedBaseNamespace,
namespaces: {
"": {
@@ -209,6 +212,7 @@ describe("defineStoreWithShorthands", () => {
} as const;

const expectedConfig = {
multipleNamespaces: false,
...expectedBaseNamespace,
namespaces: {
"": {
45 changes: 30 additions & 15 deletions packages/store/ts/config/v2/storeWithShorthands.ts
Original file line number Diff line number Diff line change
@@ -4,18 +4,23 @@ import { isTableShorthandInput, resolveTableShorthand } from "./tableShorthand";
import { hasOwnKey, isObject } from "./generics";
import { NamespaceWithShorthandsInput, StoreWithShorthandsInput } from "./input";
import { resolveNamespaceWithShorthands, validateNamespaceWithShorthands } from "./namespaceWithShorthands";
import { show } from "@arktype/util";
import { CONFIG_DEFAULTS } from "./defaults";
import { resolveNamespacesWithShorthands } from "./namespacesWithShorthands";

// TODO: this isn't finished yet

export type validateStoreWithShorthands<input> = validateNamespaceWithShorthands<input> & {
[key in keyof Omit<input, keyof NamespaceWithShorthandsInput>]: key extends "namespaces"
? {
[namespaceLabel in keyof input[key]]: validateNamespaceWithShorthands<
input[key][namespaceLabel],
extendedScope<input>
>;
}
: validateStore<input>[key];
export type validateStoreWithShorthands<input> = {
[key in keyof input]: key extends keyof NamespaceWithShorthandsInput
? validateNamespaceWithShorthands<input, extendedScope<input>>[key]
: key extends "namespaces"
? {
[namespaceLabel in keyof input[key]]: validateNamespaceWithShorthands<
input[key][namespaceLabel],
extendedScope<input>
>;
}
: validateStore<input>[key];
};

export function validateStoreWithShorthands(input: unknown): asserts input is StoreWithShorthandsInput {
@@ -26,11 +31,21 @@ export function validateStoreWithShorthands(input: unknown): asserts input is St
}
}

export type resolveStoreWithShorthands<input> = resolveStore<{
[key in keyof input]: key extends keyof NamespaceWithShorthandsInput
? resolveNamespaceWithShorthands<input[key], extendedScope<input>>
: input[key];
}>;
export type resolveStoreWithShorthands<input> = Omit<resolveStore<input>, "tables" | "namespaces"> & {
readonly tables: resolveNamespaceWithShorthands<input, extendedScope<input>>["tables"];
readonly namespaces: resolveNamespacesWithShorthands<
"namespaces" extends keyof input
? input["namespaces"]
: {
readonly [label in "namespace" extends keyof input
? input["namespace"] extends string
? input["namespace"]
: CONFIG_DEFAULTS["namespace"]
: CONFIG_DEFAULTS["namespace"]]: input;
},
extendedScope<input>
>;
};

export function resolveStoreWithShorthands<const input extends StoreWithShorthandsInput>(
input: input,
@@ -53,7 +68,7 @@ export function resolveStoreWithShorthands<const input extends StoreWithShorthan

export function defineStoreWithShorthands<const input>(
input: validateStoreWithShorthands<input>,
): resolveStoreWithShorthands<input> {
): show<resolveStoreWithShorthands<input>> {
validateStoreWithShorthands(input);
return resolveStoreWithShorthands(input) as never;
}
19 changes: 13 additions & 6 deletions packages/store/ts/config/v2/tableShorthand.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { ErrorMessage, conform } from "@arktype/util";
import { ErrorMessage, conform, merge } from "@arktype/util";
import { FixedArrayAbiType, isFixedArrayAbiType, isStaticAbiType } from "@latticexyz/schema-type/internal";
import { get, hasOwnKey, isObject } from "./generics";
import { isSchemaInput } from "./schema";
import { AbiTypeScope, Scope, getStaticAbiTypeKeys } from "./scope";
import { SchemaInput, ScopedSchemaInput, TablesWithShorthandsInput } from "./input";
import { TableShorthandInput } from "./input";
import { ValidateTableOptions, validateTable } from "./table";
import { ValidateTableOptions, resolveTable, validateTable } from "./table";

export const NoStaticKeyFieldError =
"Invalid schema. Expected an `id` field with a static ABI type or an explicit `key` option.";
@@ -114,12 +114,19 @@ export function defineTableShorthand<shorthand, scope extends Scope = AbiTypeSco
* If a shorthand is provided, it is resolved to a full config.
* If a full config is provided, it is passed through.
*/
export type resolveTableWithShorthand<table, scope extends Scope = AbiTypeScope> = table extends TableShorthandInput
? resolveTableShorthand<table, scope>
: table;
export type resolveTableWithShorthand<table, scope extends Scope = AbiTypeScope> = resolveTable<
table extends TableShorthandInput ? resolveTableShorthand<table, scope> : table,
scope
>;

export type resolveTablesWithShorthands<input, scope extends Scope = AbiTypeScope> = {
readonly [label in keyof input]: resolveTableWithShorthand<input[label], scope>;
readonly [label in keyof input]: resolveTable<
merge<
input[label] extends TableShorthandInput ? resolveTableShorthand<input[label], scope> : input[label],
{ label: label }
>,
scope
>;
};

export type validateTablesWithShorthands<tables, scope extends Scope = AbiTypeScope> = {

0 comments on commit cad0ffb

Please sign in to comment.