Skip to content

Commit

Permalink
Add support for functions with plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
lxsmnsyc committed Jan 26, 2025
1 parent 8554d15 commit be53f18
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 63 deletions.
23 changes: 8 additions & 15 deletions packages/plugins/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,20 @@
"name": "seroval-plugins",
"type": "module",
"version": "1.2.0",
"files": [
"dist",
"web"
],
"files": ["dist", "web"],
"engines": {
"node": ">=10"
},
"license": "MIT",
"keywords": [
"pridepack"
],
"keywords": ["pridepack"],
"devDependencies": {
"@types/node": "^22.10.2",
"@vitest/ui": "^2.1.8",
"pridepack": "2.6.1",
"@types/node": "^22.10.10",
"@vitest/ui": "^3.0.4",
"pridepack": "2.6.4",
"seroval": "1.2.0",
"tslib": "^2.8.1",
"typescript": "^5.7.2",
"vitest": "^2.1.8"
"typescript": "^5.7.3",
"vitest": "^3.0.4"
},
"peerDependencies": {
"seroval": "^1.0"
Expand Down Expand Up @@ -63,9 +58,7 @@
},
"typesVersions": {
"*": {
"web": [
"./dist/types/web/index.d.ts"
]
"web": ["./dist/types/web/index.d.ts"]
}
}
}
19 changes: 7 additions & 12 deletions packages/seroval/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,20 @@
"name": "seroval",
"type": "module",
"version": "1.2.0",
"files": [
"dist",
"src"
],
"files": ["dist", "src"],
"engines": {
"node": ">=10"
},
"license": "MIT",
"keywords": [
"pridepack"
],
"keywords": ["pridepack"],
"devDependencies": {
"@types/node": "^22.10.2",
"@vitest/ui": "^2.1.8",
"pridepack": "2.6.3",
"@types/node": "^22.10.10",
"@vitest/ui": "^3.0.4",
"pridepack": "2.6.4",
"ts-prune": "^0.10.3",
"tslib": "^2.8.1",
"typescript": "^5.7.2",
"vitest": "^2.1.8"
"typescript": "^5.7.3",
"vitest": "^3.0.4"
},
"scripts": {
"prepublishOnly": "pridepack clean && pridepack build",
Expand Down
47 changes: 15 additions & 32 deletions packages/seroval/src/core/context/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,24 +39,24 @@ export interface BaseParserContextOptions extends PluginAccessOptions {
refs?: Map<unknown, number>;
}

const enum NodeType {
export const enum ParserNodeType {
Fresh = 0,
Indexed = 1,
Referenced = 2,
}

interface FreshNode {
type: NodeType.Fresh;
export interface FreshNode {
type: ParserNodeType.Fresh;
value: number;
}

interface IndexedNode {
type: NodeType.Indexed;
export interface IndexedNode {
type: ParserNodeType.Indexed;
value: SerovalIndexedValueNode;
}

interface ReferencedNode {
type: NodeType.Referenced;
export interface ReferencedNode {
type: ParserNodeType.Referenced;
value: SerovalReferenceNode;
}

Expand Down Expand Up @@ -92,54 +92,37 @@ export abstract class BaseParserContext implements PluginAccessOptions {
if (registeredId != null) {
this.markRef(registeredId);
return {
type: NodeType.Indexed,
type: ParserNodeType.Indexed,
value: createIndexedValueNode(registeredId),
};
}
const id = this.refs.size;
this.refs.set(current, id);
return {
type: NodeType.Fresh,
type: ParserNodeType.Fresh,
value: id,
};
}

protected getReference<T>(current: T): ObjectNode {
const indexed = this.getIndexedValue(current);
if (indexed.type === NodeType.Indexed) {
if (indexed.type === ParserNodeType.Indexed) {
return indexed;
}
if (hasReferenceID(current)) {
return {
type: NodeType.Referenced,
type: ParserNodeType.Referenced,
value: createReferenceNode(indexed.value, current),
};
}
return indexed;
}

protected getStrictReference<T>(
current: T,
): SerovalIndexedValueNode | SerovalReferenceNode {
assert(hasReferenceID(current), new SerovalUnsupportedTypeError(current));
const result = this.getIndexedValue(current);
if (result.type === NodeType.Indexed) {
return result.value;
}
return createReferenceNode(result.value, current);
}

protected parseFunction(
current: (...args: unknown[]) => unknown,
): SerovalNode {
return this.getStrictReference(current);
}

protected parseWellKnownSymbol(
current: symbol,
): SerovalIndexedValueNode | SerovalWKSymbolNode | SerovalReferenceNode {
const ref = this.getReference(current);
if (ref.type !== NodeType.Fresh) {
if (ref.type !== ParserNodeType.Fresh) {
return ref.value;
}
assert(current in INV_SYMBOL_REF, new SerovalUnsupportedTypeError(current));
Expand All @@ -150,7 +133,7 @@ export abstract class BaseParserContext implements PluginAccessOptions {
ref: SpecialReference,
): SerovalIndexedValueNode | SerovalSpecialReferenceNode {
const result = this.getIndexedValue(SPECIAL_REFS[ref]);
if (result.type === NodeType.Indexed) {
if (result.type === ParserNodeType.Indexed) {
return result.value;
}
return createSerovalNode(
Expand All @@ -173,7 +156,7 @@ export abstract class BaseParserContext implements PluginAccessOptions {
| SerovalIndexedValueNode
| SerovalIteratorFactoryNode {
const result = this.getIndexedValue(ITERATOR);
if (result.type === NodeType.Indexed) {
if (result.type === ParserNodeType.Indexed) {
return result.value;
}
return createSerovalNode(
Expand All @@ -196,7 +179,7 @@ export abstract class BaseParserContext implements PluginAccessOptions {
| SerovalIndexedValueNode
| SerovalAsyncIteratorFactoryNode {
const result = this.getIndexedValue(ASYNC_ITERATOR);
if (result.type === NodeType.Indexed) {
if (result.type === ParserNodeType.Indexed) {
return result.value;
}
return createSerovalNode(
Expand Down
21 changes: 17 additions & 4 deletions packages/seroval/src/core/context/parser/sync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ import type {
TypedArrayValue,
} from '../../utils/typed-array';
import type { BaseParserContextOptions } from '../parser';
import { BaseParserContext } from '../parser';
import { BaseParserContext, ParserNodeType } from '../parser';

type ObjectLikeNode = SerovalObjectNode | SerovalNullConstructorNode;

Expand Down Expand Up @@ -389,6 +389,18 @@ export default abstract class BaseSyncParserContext extends BaseParserContext {
throw new SerovalUnsupportedTypeError(current);
}

protected parseFunction(current: unknown): SerovalNode {
const ref = this.getReference(current);
if (ref.type !== ParserNodeType.Fresh) {
return ref.value;
}
const plugin = this.parsePlugin(ref.value, current);
if (plugin) {
return plugin;
}
throw new SerovalUnsupportedTypeError(current);
}

parse<T>(current: T): SerovalNode {
try {
switch (typeof current) {
Expand All @@ -405,16 +417,17 @@ export default abstract class BaseSyncParserContext extends BaseParserContext {
case 'object': {
if (current) {
const ref = this.getReference(current);
return ref.type === 0
return ref.type === ParserNodeType.Fresh
? this.parseObject(ref.value, current as object)
: ref.value;
}
return NULL_NODE;
}
case 'symbol':
return this.parseWellKnownSymbol(current);
case 'function':
return this.parseFunction(current as (...args: unknown[]) => unknown);
case 'function': {
return this.parseFunction(current as unknown);
}
default:
throw new SerovalUnsupportedTypeError(current);
}
Expand Down

0 comments on commit be53f18

Please sign in to comment.