WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
26 changes: 22 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,26 @@
"type": "github",
"url": "https://github.com/sponsors/streamich"
},
"keywords": ["json-type", "type", "schema", "json-schema", "jtd", "json", "pointer", "jit"],
"keywords": [
"json-type",
"type",
"schema",
"json-schema",
"jtd",
"json",
"pointer",
"jit"
],
"engines": {
"node": ">=10.0"
},
"main": "lib/index.js",
"types": "lib/index.d.ts",
"typings": "lib/index.d.ts",
"files": ["LICENSE", "lib/"],
"files": [
"LICENSE",
"lib/"
],
"license": "Apache-2.0",
"scripts": {
"format": "biome format ./src",
Expand Down Expand Up @@ -51,6 +63,7 @@
"@jsonjoy.com/json-random": "^1.2.0",
"@jsonjoy.com/util": "^1.9.0",
"sonic-forest": "^1.2.1",
"thingies": "^2.5.0",
"tree-dump": "^1.0.3"
},
"devDependencies": {
Expand All @@ -67,11 +80,16 @@
"typescript": "^5.6.2"
},
"jest": {
"moduleFileExtensions": ["ts", "js"],
"moduleFileExtensions": [
"ts",
"js"
],
"transform": {
"^.+\\.ts$": "ts-jest"
},
"transformIgnorePatterns": [".*/node_modules/.*"],
"transformIgnorePatterns": [
".*/node_modules/.*"
],
"testRegex": ".*/(__tests__|__jest__|demo)/.*\\.(test|spec)\\.ts$"
}
}
26 changes: 25 additions & 1 deletion src/codegen/binary/AbstractBinaryCodegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,32 @@ var uint8 = writer.uint8, view = writer.view;`,
return this.codegen.compile();
}

protected abstract linkGet(): void;

protected onAny(path: SchemaPath, r: JsExpression, type: AnyType): void {
this.codegen.js(`encoder.writeAny(${r.use()});`);
const codegen = this.codegen;
const rv = codegen.var(r.use());
codegen.link('Value');
this.linkGet();
codegen.if(
/* js */ `${rv} instanceof Value`,
() => {
const rType = codegen.var(/* js */ `${rv}.type`);
const rData = codegen.var(/* js */ `${rv}.data`);
codegen.if(
/* js */ `${rType}`,
() => {
codegen.js(/* js */ `get(${rType})(${rData},encoder);`);
},
() => {
this.codegen.js(`encoder.writeAny(${rData});`);
},
);
},
() => {
this.codegen.js(`encoder.writeAny(${rv});`);
},
);
}

protected onCon(path: SchemaPath, r: JsExpression, type: ConType): void {
Expand Down
8 changes: 7 additions & 1 deletion src/codegen/binary/cbor/CborCodegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import {JsExpression} from '@jsonjoy.com/codegen/lib/util/JsExpression';
import {normalizeAccessor} from '@jsonjoy.com/codegen/lib/util/normalizeAccessor';
import {CborEncoder} from '@jsonjoy.com/json-pack/lib/cbor/CborEncoder';
import {KeyOptType, type KeyType, type ObjType, type Type} from '../../../type';
import type {CompiledBinaryEncoder, SchemaPath} from '../../types';
import {lazyKeyedFactory} from '../../util';
import {AbstractBinaryCodegen} from '../AbstractBinaryCodegen';
import {writer} from '../writer';
import {once} from 'thingies/lib/once';
import type {CompiledBinaryEncoder, SchemaPath} from '../../types';

export class CborCodegen extends AbstractBinaryCodegen<CborEncoder> {
public static readonly get = lazyKeyedFactory((type: Type, name?: string) => {
Expand All @@ -18,6 +19,11 @@ export class CborCodegen extends AbstractBinaryCodegen<CborEncoder> {

protected encoder = new CborEncoder(writer);

@once
protected linkGet(): void {
this.codegen.linkDependency(CborCodegen.get, 'get');
}

protected onObj(path: SchemaPath, value: JsExpression, type: ObjType): void {
const codegen = this.codegen;
const r = codegen.r();
Expand Down
42 changes: 40 additions & 2 deletions src/codegen/binary/cbor/__tests__/CborCodegen.spec.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,52 @@
import {Writer} from '@jsonjoy.com/buffers/lib/Writer';
import {CborDecoder} from '@jsonjoy.com/json-pack/lib/cbor/CborDecoder';
import {CborEncoder} from '@jsonjoy.com/json-pack/lib/cbor/CborEncoder';
import type {Type} from '../../../../type';
import type {ModuleType} from '../../../../type/classes/ModuleType';
import {ModuleType} from '../../../../type/classes/ModuleType';
import {testBinaryCodegen} from '../../__tests__/testBinaryCodegen';
import {CborCodegen} from '../CborCodegen';
import {unknown, Value} from '../../../../value';
import type {Type} from '../../../../type';

const encoder = new CborEncoder(new Writer(16));
const decoder = new CborDecoder();

describe('inline Value', () => {
test('can encode "any" field', () => {
const {t} = new ModuleType();
const type = t.object({foo: t.any});
const fn = CborCodegen.get(type);
encoder.writer.reset();
fn({foo: true}, encoder);
const encoded = encoder.writer.flush();
const decoded = decoder.decode(encoded);
expect(decoded).toEqual({foo: true});
});

test('can encode anon Value<unknown>', () => {
const {t} = new ModuleType();
const type = t.object({foo: t.any});
const fn = CborCodegen.get(type);
encoder.writer.reset();
const value = unknown('test');
fn({foo: value}, encoder);
const encoded = encoder.writer.flush();
const decoded = decoder.decode(encoded);
expect(decoded).toEqual({foo: 'test'});
});

test('can encode typed Value<T>', () => {
const {t} = new ModuleType();
const type = t.object({foo: t.any});
const fn = CborCodegen.get(type);
encoder.writer.reset();
const value = new Value(123, t.con(123));
fn({foo: value}, encoder);
const encoded = encoder.writer.flush();
const decoded = decoder.decode(encoded);
expect(decoded).toEqual({foo: 123});
});
});

const transcode = (system: ModuleType, type: Type, value: unknown) => {
const fn = CborCodegen.get(type);
encoder.writer.reset();
Expand Down
8 changes: 7 additions & 1 deletion src/codegen/binary/json/JsonCodegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import {JsExpression} from '@jsonjoy.com/codegen/lib/util/JsExpression';
import {normalizeAccessor} from '@jsonjoy.com/codegen/lib/util/normalizeAccessor';
import {JsonEncoder} from '@jsonjoy.com/json-pack/lib/json/JsonEncoder';
import {type ArrType, type MapType, KeyOptType, type KeyType, type ObjType, type Type} from '../../../type';
import type {CompiledBinaryEncoder, SchemaPath} from '../../types';
import {lazyKeyedFactory} from '../../util';
import {AbstractBinaryCodegen} from '../AbstractBinaryCodegen';
import {writer} from '../writer';
import {once} from 'thingies/lib/once';
import type {CompiledBinaryEncoder, SchemaPath} from '../../types';

export class JsonCodegen extends AbstractBinaryCodegen<JsonEncoder> {
public static readonly get = lazyKeyedFactory((type: Type, name?: string) => {
Expand All @@ -20,6 +21,11 @@ export class JsonCodegen extends AbstractBinaryCodegen<JsonEncoder> {

protected encoder = new JsonEncoder(writer);

@once
protected linkGet(): void {
this.codegen.linkDependency(JsonCodegen.get, 'get');
}

protected onArr(path: SchemaPath, r: JsExpression, type: ArrType): void {
const codegen = this.codegen;
const rLen = codegen.var(/* js */ `${r.use()}.length`);
Expand Down
40 changes: 40 additions & 0 deletions src/codegen/binary/json/__tests__/JsonCodegen.spec.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,52 @@
import {Writer} from '@jsonjoy.com/buffers/lib/Writer';
import {parse} from '@jsonjoy.com/json-pack/lib/json-binary';
import {JsonEncoder} from '@jsonjoy.com/json-pack/lib/json/JsonEncoder';
import {JsonDecoder} from '@jsonjoy.com/json-pack/lib/json/JsonDecoder';
import {ModuleType} from '../../../../type/classes/ModuleType';
import {testBinaryCodegen} from '../../__tests__/testBinaryCodegen';
import {JsonCodegen} from '../JsonCodegen';
import type {Type} from '../../../../type';
import {unknown, Value} from '../../../../value';

const encoder = new JsonEncoder(new Writer(16));
const decoder = new JsonDecoder();

describe('inline Value', () => {
test('can encode "any" field', () => {
const {t} = new ModuleType();
const type = t.object({foo: t.any});
const fn = JsonCodegen.get(type);
encoder.writer.reset();
fn({foo: true}, encoder);
const encoded = encoder.writer.flush();
const decoded = decoder.decode(encoded);
expect(decoded).toEqual({foo: true});
});

test('can encode anon Value<unknown>', () => {
const {t} = new ModuleType();
const type = t.object({foo: t.any});
const fn = JsonCodegen.get(type);
encoder.writer.reset();
const value = unknown('test');
fn({foo: value}, encoder);
const encoded = encoder.writer.flush();
const decoded = decoder.decode(encoded);
expect(decoded).toEqual({foo: 'test'});
});

test('can encode typed Value<T>', () => {
const {t} = new ModuleType();
const type = t.object({foo: t.any});
const fn = JsonCodegen.get(type);
encoder.writer.reset();
const value = new Value(123, t.con(123));
fn({foo: value}, encoder);
const encoded = encoder.writer.flush();
const decoded = decoder.decode(encoded);
expect(decoded).toEqual({foo: 123});
});
});

const transcode = (system: ModuleType, type: Type, value: unknown) => {
const fn = JsonCodegen.get(type);
Expand Down
8 changes: 7 additions & 1 deletion src/codegen/binary/msgpack/MsgPackCodegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import {JsExpression} from '@jsonjoy.com/codegen/lib/util/JsExpression';
import {normalizeAccessor} from '@jsonjoy.com/codegen/lib/util/normalizeAccessor';
import {MsgPackEncoder} from '@jsonjoy.com/json-pack/lib/msgpack/MsgPackEncoder';
import {KeyOptType, type KeyType, type ObjType, type Type} from '../../../type';
import type {CompiledBinaryEncoder, SchemaPath} from '../../types';
import {lazyKeyedFactory} from '../../util';
import {AbstractBinaryCodegen} from '../AbstractBinaryCodegen';
import {writer} from '../writer';
import {once} from 'thingies/lib/once';
import type {CompiledBinaryEncoder, SchemaPath} from '../../types';

export class MsgPackCodegen extends AbstractBinaryCodegen<MsgPackEncoder> {
public static readonly get = lazyKeyedFactory((type: Type, name?: string) => {
Expand All @@ -18,6 +19,11 @@ export class MsgPackCodegen extends AbstractBinaryCodegen<MsgPackEncoder> {

protected encoder = new MsgPackEncoder(writer);

@once
protected linkGet(): void {
this.codegen.linkDependency(MsgPackCodegen.get, 'get');
}

protected onObj(path: SchemaPath, value: JsExpression, type: ObjType): void {
const codegen = this.codegen;
const r = codegen.r();
Expand Down
40 changes: 39 additions & 1 deletion src/codegen/binary/msgpack/__tests__/MsgPackCodegen.spec.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,51 @@
import {Writer} from '@jsonjoy.com/buffers/lib/Writer';
import {MsgPackDecoder} from '@jsonjoy.com/json-pack/lib/msgpack/MsgPackDecoder';
import {MsgPackEncoder} from '@jsonjoy.com/json-pack/lib/msgpack/MsgPackEncoder';
import type {ModuleType, Type} from '../../../../type';
import {ModuleType, type Type} from '../../../../type';
import {testBinaryCodegen} from '../../__tests__/testBinaryCodegen';
import {MsgPackCodegen} from '../MsgPackCodegen';
import {unknown, Value} from '../../../../value';

const encoder = new MsgPackEncoder(new Writer(16));
const decoder = new MsgPackDecoder();

describe('inline Value', () => {
test('can encode "any" field', () => {
const {t} = new ModuleType();
const type = t.object({foo: t.any});
const fn = MsgPackCodegen.get(type);
encoder.writer.reset();
fn({foo: true}, encoder);
const encoded = encoder.writer.flush();
const decoded = decoder.decode(encoded);
expect(decoded).toEqual({foo: true});
});

test('can encode anon Value<unknown>', () => {
const {t} = new ModuleType();
const type = t.object({foo: t.any});
const fn = MsgPackCodegen.get(type);
encoder.writer.reset();
const value = unknown('test');
fn({foo: value}, encoder);
const encoded = encoder.writer.flush();
const decoded = decoder.decode(encoded);
expect(decoded).toEqual({foo: 'test'});
});

test('can encode typed Value<T>', () => {
const {t} = new ModuleType();
const type = t.object({foo: t.any});
const fn = MsgPackCodegen.get(type);
encoder.writer.reset();
const value = new Value(123, t.con(123));
fn({foo: value}, encoder);
const encoded = encoder.writer.flush();
const decoded = decoder.decode(encoded);
expect(decoded).toEqual({foo: 123});
});
});

const transcode = (system: ModuleType, type: Type, value: unknown) => {
const fn = MsgPackCodegen.get(type);
encoder.writer.reset();
Expand Down
27 changes: 26 additions & 1 deletion src/codegen/capacity/CapacityEstimatorCodegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {DiscriminatorCodegen} from '../discriminator';
import {lazyKeyedFactory} from '../util';
import {AbstractCodegen} from '../AbstractCodege';
import type {SchemaPath} from '../types';
import {Value} from '../../value';

export type CompiledCapacityEstimator = (value: unknown) => number;

Expand Down Expand Up @@ -36,6 +37,10 @@ export class CapacityEstimatorCodegen extends AbstractCodegen<CompiledCapacityEs
args: ['r0'],
prologue: /* js */ `var size = 0;`,
epilogue: /* js */ `return size;`,
linkable: {
Value,
get: CapacityEstimatorCodegen.get,
},
processSteps: (steps) => {
const stepsJoined: CodegenStepExecJs[] = [];
for (let i = 0; i < steps.length; i++) {
Expand All @@ -58,7 +63,27 @@ export class CapacityEstimatorCodegen extends AbstractCodegen<CompiledCapacityEs
protected onAny(path: SchemaPath, r: JsExpression, type: AnyType): void {
const codegen = this.codegen;
const rv = codegen.var(r.use());
codegen.js(/* js */ `size += maxEncodingCapacity(${rv});`);
codegen.link('Value');
codegen.link('get');
codegen.if(
/* js */ `${rv} instanceof Value`,
() => {
const rType = codegen.var(/* js */ `${rv}.type`);
const rData = codegen.var(/* js */ `${rv}.data`);
codegen.if(
/* js */ `${rType}`,
() => {
codegen.js(/* js */ `size += get(${rType})(${rData});`);
},
() => {
codegen.js(/* js */ `size += maxEncodingCapacity(${rData});`);
},
);
},
() => {
codegen.js(/* js */ `size += maxEncodingCapacity(${rv});`);
},
);
}

protected onCon(path: SchemaPath, r: JsExpression, type: ConType): void {
Expand Down
Loading