Skip to main content
Glama
serialize.md4.61 kB
# Serialize The `Serialize` macro generates JSON serialization methods with **cycle detection** and object identity tracking. This enables serialization of complex object graphs including circular references. ## Generated Methods | Type | Generated Code | Description | |------|----------------|-------------| | Class | `classNameSerialize(value)` + `static serialize(value)` | Standalone function + static wrapper method | | Enum | `enumNameSerialize(value)`, `enumNameSerializeWithContext` | Standalone functions | | Interface | `interfaceNameSerialize(value)`, etc. | Standalone functions | | Type Alias | `typeNameSerialize(value)`, etc. | Standalone functions | ## Cycle Detection Protocol The generated code handles circular references using `__id` and `__ref` markers: ```json { "__type": "User", "__id": 1, "name": "Alice", "friend": { "__ref": 2 } // Reference to object with __id: 2 } ``` When an object is serialized: 1. Check if it's already been serialized (has an `__id`) 2. If so, return `{ "__ref": existingId }` instead 3. Otherwise, register the object and serialize its fields ## Type-Specific Serialization | Type | Serialization Strategy | |------|------------------------| | Primitives | Direct value | | `Date` | `toISOString()` | | Arrays | For primitive-like element types, pass through; for `Date`/`Date | null`, map to ISO strings; otherwise map and call `SerializeWithContext(ctx)` when available | | `Map<K,V>` | For primitive-like values, `Object.fromEntries(map.entries())`; for `Date`/`Date | null`, convert to ISO strings; otherwise call `SerializeWithContext(ctx)` per value when available | | `Set<T>` | Convert to array; element handling matches `Array<T>` | | Nullable | Include `null` explicitly; for primitive-like and `Date` unions the generator avoids runtime `SerializeWithContext` checks | | Objects | Call `SerializeWithContext(ctx)` if available (to support user-defined implementations) | Note: the generator specializes some code paths based on the declared TypeScript type to avoid runtime feature detection on primitives and literal unions. ## Field-Level Options The `@serde` decorator supports: - `skip` / `skipSerializing` - Exclude field from serialization - `rename = "jsonKey"` - Use different JSON property name - `flatten` - Merge nested object's fields into parent ## Example ```typescript before /** @derive(Serialize) */ class User { id: number; /** @serde({ rename: "userName" }) */ name: string; /** @serde({ skipSerializing: true }) */ password: string; /** @serde({ flatten: true }) */ metadata: UserMetadata; } ``` ```typescript after import { SerializeContext } from 'macroforge/serde'; class User { id: number; name: string; password: string; metadata: UserMetadata; /** Serializes a value to a JSON string. @param value - The value to serialize @returns JSON string representation with cycle detection metadata */ static serialize(value: User): string { return userSerialize(value); } /** @internal Serializes with an existing context for nested/cyclic object graphs. @param value - The value to serialize @param ctx - The serialization context */ static serializeWithContext(value: User, ctx: @{SERIALIZE_CONTEXT}): Record<string, unknown> { return userSerializeWithContext(value, ctx); } } /** Serializes a value to a JSON string. @param value - The value to serialize @returns JSON string representation with cycle detection metadata */ export function userSerialize( value: User ): string { const ctx = @{SERIALIZE_CONTEXT}.create(); return JSON.stringify(userSerializeWithContext(value, ctx)); } /** @internal Serializes with an existing context for nested/cyclic object graphs. @param value - The value to serialize @param ctx - The serialization context */ export function userSerializeWithContext( value: User, ctx: SerializeContext ): Record<string, unknown> { const existingId = ctx.getId(value); if (existingId !== undefined) { return { __ref: existingId }; } const __id = ctx.register(value); const result: Record<string, unknown> = { __type: 'User', __id }; result['id'] = value.id; result['userName'] = value.name; { const __flattened = userMetadataSerializeWithContext(value.metadata, ctx); const { __type: _, __id: __, ...rest } = __flattened as any; Object.assign(result, rest); } return result; } ``` ## Required Import The generated code automatically imports `SerializeContext` from `macroforge/serde`.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/macroforge-ts/mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server