From 9827bc9e7db047f1efae41bf9f2291af420b40d9 Mon Sep 17 00:00:00 2001 From: Jason Kuhrt Date: Sun, 30 Jun 2024 20:59:33 -0400 Subject: [PATCH] feat: scalar constructor with inference (#954) --- src/entrypoints/alpha/_Graffle.ts | 2 ++ src/entrypoints/alpha/__Graffle.ts | 1 + src/entrypoints/alpha/main.ts | 2 +- src/entrypoints/alpha/scalars.ts | 2 +- .../1_Schema/Hybrid/types/Scalar/Scalar.ts | 31 +++++++++++++------ .../1_Schema/Hybrid/types/Scalar/codec.ts | 15 ++++----- .../Hybrid/types/Scalar/nativeScalarCodecs.ts | 22 ++++++------- tests/_/customScalarCodecs.ts | 9 +++--- 8 files changed, 50 insertions(+), 34 deletions(-) create mode 100644 src/entrypoints/alpha/_Graffle.ts create mode 100644 src/entrypoints/alpha/__Graffle.ts diff --git a/src/entrypoints/alpha/_Graffle.ts b/src/entrypoints/alpha/_Graffle.ts new file mode 100644 index 000000000..e140fdb5a --- /dev/null +++ b/src/entrypoints/alpha/_Graffle.ts @@ -0,0 +1,2 @@ +export * from '../../layers/5_client/client.js' +export * as Scalars from './scalars.js' diff --git a/src/entrypoints/alpha/__Graffle.ts b/src/entrypoints/alpha/__Graffle.ts new file mode 100644 index 000000000..de55bad64 --- /dev/null +++ b/src/entrypoints/alpha/__Graffle.ts @@ -0,0 +1 @@ +export * as Graffle from './_Graffle.js' diff --git a/src/entrypoints/alpha/main.ts b/src/entrypoints/alpha/main.ts index 4620dc77e..adb68dd33 100644 --- a/src/entrypoints/alpha/main.ts +++ b/src/entrypoints/alpha/main.ts @@ -1,3 +1,3 @@ export { execute } from '../../layers/0_functions/execute.js' export { request } from '../../layers/0_functions/request.js' -export * as Graffle from '../../layers/5_client/client.js' +export * from './__Graffle.js' diff --git a/src/entrypoints/alpha/scalars.ts b/src/entrypoints/alpha/scalars.ts index ff0f7eb4e..60a65c66d 100644 --- a/src/entrypoints/alpha/scalars.ts +++ b/src/entrypoints/alpha/scalars.ts @@ -1 +1 @@ -export * from '../../layers/1_Schema/Hybrid/types/Scalar/Scalar.js' +export { create } from '../../layers/1_Schema/Hybrid/types/Scalar/Scalar.js' diff --git a/src/layers/1_Schema/Hybrid/types/Scalar/Scalar.ts b/src/layers/1_Schema/Hybrid/types/Scalar/Scalar.ts index d8043b63b..1518d9dea 100644 --- a/src/layers/1_Schema/Hybrid/types/Scalar/Scalar.ts +++ b/src/layers/1_Schema/Hybrid/types/Scalar/Scalar.ts @@ -2,9 +2,9 @@ import type { GlobalRegistry } from '../../../../2_generator/globalRegistry.js' import type { Codec } from './codec.js' -import { nativeScalarCodecs } from './nativeScalarCodecs.js' +import { JavaScriptScalarCodecs } from './nativeScalarCodecs.js' -export { nativeScalarCodecs } from './nativeScalarCodecs.js' +export { JavaScriptScalarCodecs } from './nativeScalarCodecs.js' export const ScalarKind = `Scalar` @@ -12,6 +12,18 @@ export type ScalarKind = typeof ScalarKind export type StandardScalarRuntimeTypes = boolean | number | string +export const create = <$Name extends string, $Decoded, $Encoded extends StandardScalarRuntimeTypes>( + name: $Name, + codec: { + encode: (value: $Decoded) => $Encoded + decode: (value: $Encoded) => $Decoded + }, +): Scalar<$Name, $Decoded, $Encoded> => ({ + kind: ScalarKind, + name: name, + codec: codec as any, // eslint-disable-line +}) + export const scalar = <$Name extends string, $Codec extends Codec>( name: $Name, codec: $Codec, @@ -23,22 +35,23 @@ export const scalar = <$Name extends string, $Codec extends Codec>( export interface Scalar< $Name extends string = string, - $Codec extends Codec = Codec, + $Decoded = unknown, + $Encoded extends StandardScalarRuntimeTypes = StandardScalarRuntimeTypes, > { kind: ScalarKind name: $Name - codec: $Codec + codec: Codec<$Decoded, $Encoded> } -export const String = scalar(`String`, nativeScalarCodecs.String) +export const String = create(`String`, JavaScriptScalarCodecs.String) -export const ID = scalar(`ID`, nativeScalarCodecs.String) +export const ID = create(`ID`, JavaScriptScalarCodecs.String) -export const Int = scalar(`Int`, nativeScalarCodecs.Number) +export const Int = create(`Int`, JavaScriptScalarCodecs.Number) -export const Float = scalar(`Float`, nativeScalarCodecs.Number) +export const Float = create(`Float`, JavaScriptScalarCodecs.Number) -export const Boolean = scalar(`Boolean`, nativeScalarCodecs.Boolean) +export const Boolean = create(`Boolean`, JavaScriptScalarCodecs.Boolean) export type ID = typeof ID diff --git a/src/layers/1_Schema/Hybrid/types/Scalar/codec.ts b/src/layers/1_Schema/Hybrid/types/Scalar/codec.ts index 2072f6694..448c6637e 100644 --- a/src/layers/1_Schema/Hybrid/types/Scalar/codec.ts +++ b/src/layers/1_Schema/Hybrid/types/Scalar/codec.ts @@ -1,10 +1,11 @@ import type { StandardScalarRuntimeTypes } from './Scalar.js' -export const codec = ( - codec: Codec, -) => codec - -export type Codec = { - encode: (value: Decoded) => Encoded - decode: (value: Encoded) => Decoded +export type Codec<$Decoded = any, $Encoded extends StandardScalarRuntimeTypes = StandardScalarRuntimeTypes> = { + encode: (value: $Decoded) => $Encoded + decode: (value: $Encoded) => $Decoded } + +export const createCodec = <$Decoded, $Encoded extends StandardScalarRuntimeTypes>(codec: { + encode: (value: $Decoded) => $Encoded + decode: (value: $Encoded) => $Decoded +}): Codec<$Decoded, $Encoded> => codec diff --git a/src/layers/1_Schema/Hybrid/types/Scalar/nativeScalarCodecs.ts b/src/layers/1_Schema/Hybrid/types/Scalar/nativeScalarCodecs.ts index b4441e6ef..8ca3bfc68 100644 --- a/src/layers/1_Schema/Hybrid/types/Scalar/nativeScalarCodecs.ts +++ b/src/layers/1_Schema/Hybrid/types/Scalar/nativeScalarCodecs.ts @@ -1,16 +1,16 @@ -import { codec } from './codec.js' +import { createCodec } from './codec.js' -export const nativeScalarCodecs = { - String: codec({ - encode: (value) => value, - decode: (value) => value, +export const JavaScriptScalarCodecs = { + String: createCodec({ + encode: (value: string) => value, + decode: (value: string) => value, }), - Number: codec({ - encode: (value) => value, - decode: (value) => value, + Number: createCodec({ + encode: (value: number) => value, + decode: (value: number) => value, }), - Boolean: codec({ - encode: (value) => value, - decode: (value) => value, + Boolean: createCodec({ + encode: (value: boolean) => value, + decode: (value: boolean) => value, }), } diff --git a/tests/_/customScalarCodecs.ts b/tests/_/customScalarCodecs.ts index 114649350..1e5eaa70e 100644 --- a/tests/_/customScalarCodecs.ts +++ b/tests/_/customScalarCodecs.ts @@ -1,9 +1,8 @@ -import { Scalar } from '../../src/layers/1_Schema/__.js' -import type { Codec } from '../../src/layers/1_Schema/Hybrid/types/Scalar/codec.js' +import { Graffle } from '../../src/entrypoints/alpha/main.js' -export const Date = Scalar.scalar<'Date', Codec>(`Date`, { - encode: value => value.toISOString(), - decode: value => new globalThis.Date(value), +export const Date = Graffle.Scalars.create(`Date`, { + encode: (value: globalThis.Date) => value.toISOString(), + decode: (value: string) => new globalThis.Date(value), }) export type Date = typeof Date