### Install Craft library via package manager Source: https://github.com/sylphxltd/craft/blob/main/README.md Demonstrates installing @sylphx/craft using various package managers. Run the appropriate command in your terminal to add the library to your project. ```Bash # Using bun (recommended) bun add @sylphx/craft # Using npm npm install @sylphx/craft # Using pnpm pnpm add @sylphx/craft # Using yarn yarn add @sylphx/craft ``` -------------------------------- ### Quick start: immutable update with craft Source: https://github.com/sylphxltd/craft/blob/main/README.md Shows a basic example of using craft to produce a new immutable state from a base object while mutating a draft inside the producer function. ```TypeScript import { craft } from "@sylphx/craft"; const baseState = { user: { name: "Alice", age: 25 }, todos: [ { id: 1, text: "Learn Craft", done: false }, { id: 2, text: "Use Craft", done: false }, ], }; const nextState = craft(baseState, (draft) => { draft.user.age = 26; draft.todos[0].done = true; draft.todos.push({ id: 3, text: "Master Craft", done: false }); }); // Original is unchanged console.log(baseState.user.age); // 25 // New state has the updates console.log(nextState.user.age); // 26 console.log(nextState.todos.length); // 3 // Structural sharing - unchanged parts are the same reference console.log(baseState.todos[1] === nextState.todos[1]); // true ``` -------------------------------- ### Craft Development Commands with Bun Source: https://github.com/sylphxltd/craft/blob/main/README.md Set of commands for managing the Craft project lifecycle, including installation, testing, linting, formatting, type checking, and building. Depends on Bun package manager; inputs are project files, outputs are reports or built artifacts. Run individually as needed. ```bash # Install dependencies bun install # Run tests bun test # Run tests in watch mode bun test:watch # Run benchmarks bun bench # Type checking bun run typecheck # Linting bun run lint # Format code bun run format # Build bun run build ``` -------------------------------- ### Immutable State Updates: Manual vs Craft Source: https://github.com/sylphxltd/craft/blob/main/README.md This example contrasts verbose manual immutable updates using spread operators with Craft's concise draft-based API for nested state changes. It requires a state object as input and produces an immutable nextState. Limitations include needing the Craft library imported; works with any mutable state structure. ```typescript // ❌ Manual (error-prone, verbose, slow) const nextState = { ...state, user: { ...state.user, profile: { ...state.user.profile, age: state.user.profile.age + 1, }, }, }; // ✅ Craft (simple, safe, fast) const nextState = craft(state, (draft) => { draft.user.profile.age++; }); ``` -------------------------------- ### Get Immutable Snapshot with current (TypeScript) Source: https://context7.com/sylphxltd/craft/llms.txt The current function gets an immutable snapshot of the current draft state. Imported from @sylphx/craft, used within a producer to capture intermediates. Outputs a frozen object, ensuring immutability for safe sharing, but limited to use inside producers. ```typescript import { craft, current } from "@sylphx/craft"; interface State { items: number[]; metadata: { lastUpdate: number }; } let snapshot: State; const state: State = { items: [1, 2, 3], metadata: { lastUpdate: 0 } }; const next = craft(state, (draft) => { draft.items.push(4); draft.items.push(5); draft.metadata.lastUpdate = Date.now(); // Get frozen snapshot for use outside producer snapshot = current(draft); }); // Snapshot is immutable and safe to share console.log(snapshot.items); // [1, 2, 3, 4, 5] console.log(Object.isFrozen(snapshot)); // true ``` -------------------------------- ### Get Immutable Snapshot of Draft State (TypeScript) Source: https://github.com/sylphxltd/craft/blob/main/README.md Provides an immutable snapshot of the current draft state within a producer function. This is useful for capturing the state at a specific point in time before further mutations occur. It relies on the `current` function from the Craft library. ```typescript let snapshot; craft(state, (draft) => { draft.items.push(4); snapshot = current(draft); // Frozen snapshot }); // Use snapshot outside producer console.log(snapshot.items); // [1, 2, 3, 4] ``` -------------------------------- ### Running Craft Benchmarks with Bun Source: https://github.com/sylphxltd/craft/blob/main/README.md Executes performance benchmarks to compare Craft against Immer across array, Map/Set, and JSON patch operations. Requires Bun runtime and project dependencies; outputs timing results to console. Best for local verification of speed claims. ```bash bun bench ``` -------------------------------- ### Fluent API with composer Source: https://github.com/sylphxltd/craft/blob/main/README.md Demonstrates the `composer` fluent interface for chaining multiple draft mutations before producing a new state. ```TypeScript const updater = composer((draft) => { draft.count++; }) .with((draft) => { draft.name = "Bob"; }) .with((draft) => { draft.active = true; }); const nextState = updater.produce(baseState); ``` -------------------------------- ### Sequential producers with pipe Source: https://github.com/sylphxltd/craft/blob/main/README.md Applies a series of producer functions in order using the `pipe` utility, returning the final immutable state. ```TypeScript const result = pipe( baseState, (draft) => { draft.count++; }, (draft) => { draft.count *= 2; }, (draft) => { draft.name = "Result"; }, ); ``` -------------------------------- ### Fluent API for chaining producers with composer Source: https://context7.com/sylphxltd/craft/llms.txt The composer function provides a fluent API for chaining multiple producers together. It allows building complex state transformations through method chaining with the .with() method, making the composition more readable and maintainable. ```typescript import { composer } from "@sylphx/craft"; interface TodoState { todos: Array<{ id: number; text: string; done: boolean }>; filter: string; count: number; } const updater = composer((draft) => { draft.count++; }) .with((draft) => { draft.filter = "active"; }) .with((draft) => { draft.todos.push({ id: 3, text: "New todo", done: false }); }); const state: TodoState = { todos: [ { id: 1, text: "Learn", done: false }, { id: 2, text: "Practice", done: true } ], filter: "all", count: 0 }; const nextState = updater.produce(state); console.log(nextState.count); // 1 console.log(nextState.filter); // "active" console.log(nextState.todos.length); // 3 ``` -------------------------------- ### Map and Set Mutations (TypeScript) Source: https://github.com/sylphxltd/craft/blob/main/README.md Demonstrates Craft's support for ES6 Map and Set collections, enabling automatic mutation tracking for these data structures. It shows how to perform operations like adding, deleting, and updating elements within Maps and Sets. ```typescript import { craft } from "@sylphx/craft"; // Map mutations const state = { users: new Map([ ["alice", { name: "Alice", age: 25 }], ["bob", { name: "Bob", age: 30 }], ]), }; const next = craft(state, (draft) => { draft.users.set("charlie", { name: "Charlie", age: 35 }); draft.users.delete("alice"); const bob = draft.users.get("bob"); if (bob) bob.age = 31; }); // Set mutations const state = { tags: new Set(["javascript", "typescript"]), }; const next = craft(state, (draft) => { draft.tags.add("react"); draft.tags.delete("javascript"); }); ``` -------------------------------- ### Combine producers using compose Source: https://github.com/sylphxltd/craft/blob/main/README.md Uses the `compose` utility to merge multiple producer functions into a single one that can be passed to `craft`. ```TypeScript const increment = (draft: State) => { draft.count++; }; const activate = (draft: State) => { draft.active = true; }; const nextState = craft(baseState, compose(increment, activate)); ``` -------------------------------- ### Generate and Apply JSON Patches (TypeScript) Source: https://github.com/sylphxltd/craft/blob/main/README.md Illustrates how to generate JSON patches (RFC 6902) to track state mutations, enabling features like undo/redo and time-travel debugging. It shows the use of `craftWithPatches` to produce patches and `applyPatches` to revert or recreate states. ```typescript import { craftWithPatches, applyPatches } from "@sylphx/craft"; const [nextState, patches, inversePatches] = craftWithPatches(state, (draft) => { draft.count = 5; draft.user.name = "Bob"; draft.items.push({ id: 3 }); }); // patches describe the changes: // [ // { op: 'replace', path: ['count'], value: 5 }, // { op: 'replace', path: ['user', 'name'], value: 'Bob' }, // { op: 'add', path: ['items', 2], value: { id: 3 } } // ] // Apply patches to recreate state const recreated = applyPatches(state, patches); console.log(recreated === nextState); // true (deep equal) // Undo changes using inverse patches const reverted = applyPatches(nextState, inversePatches); console.log(reverted === state); // true (deep equal) ``` -------------------------------- ### Pipe State with Producers (TypeScript) Source: https://context7.com/sylphxltd/craft/llms.txt The pipe function applies multiple producer functions sequentially to a base state, enabling chained state mutations. It requires the @sylphx/craft library and takes an initial state plus an array of producer functions as inputs. Outputs the final mutated state, with limitations in handling asynchronous operations. ```typescript import { pipe } from "@sylphx/craft"; interface CounterState { count: number; history: number[]; } const state: CounterState = { count: 5, history: [] }; const result = pipe( state, (draft) => { draft.history.push(draft.count); draft.count++; }, (draft) => { draft.history.push(draft.count); draft.count *= 2; }, (draft) => { draft.history.push(draft.count); draft.count += 10; } ); console.log(result); // { count: 22, history: [5, 6, 12] } ``` -------------------------------- ### Manual draft control with createDraft and finishDraft Source: https://github.com/sylphxltd/craft/blob/main/README.md Illustrates advanced usage where a draft is created manually, mutated over time (e.g., async), and then finalized into an immutable state. ```TypeScript const draft = createDraft(state); // Make changes over await fetchData().then(data => { draft.user = data; }); draft.count++; // Finalize when ready const nextState = finishDraft(draft); ``` -------------------------------- ### Apply Patches with applyPatches in TypeScript Source: https://context7.com/sylphxltd/craft/llms.txt applyPatches mutates a base state using a series of JSON Patch operations, useful for syncing or replaying history. It requires @sylphx/craft import and Patch type; inputs are base state and patches array; outputs a new patched state; supports undo/redo via inverse patches but may fail on invalid paths. ```typescript import { applyPatches, type Patch } from "@sylphx/craft"; interface AppState { todos: Array<{ id: number; text: string; done: boolean }>; filter: string; } const state: AppState = { todos: [ { id: 1, text: "Learn", done: false }, { id: 2, text: "Practice", done: false } ], filter: "all" }; // Patches from server or history const patches: Patch[] = [ { op: "replace", path: ["todos", 0, "done"], value: true }, { op: "replace", path: ["filter"], value: "active" }, { op: "add", path: ["todos", 2], value: { id: 3, text: "Master", done: false } } ]; const nextState = applyPatches(state, patches); console.log(nextState.todos[0].done); // true console.log(nextState.filter); // "active" console.log(nextState.todos.length); // 3 // Use case: Undo/Redo system const history: Patch[][] = []; const inverseHistory: Patch[][] = []; function makeChange(current: AppState, changeProducer: any): AppState { const [next, patches, inverse] = craftWithPatches(current, changeProducer); history.push(patches); inverseHistory.push(inverse); return next; } function undo(current: AppState): AppState { const inverse = inverseHistory.pop(); return inverse ? applyPatches(current, inverse) : current; } function redo(current: AppState): AppState { const patches = history[inverseHistory.length]; return patches ? applyPatches(current, patches) : current; } ``` -------------------------------- ### Core function craft usage Source: https://github.com/sylphxltd/craft/blob/main/README.md Demonstrates the primary `craft` function to mutate a draft and automatically return a new immutable state. The producer can freely modify the draft. ```TypeScript const nextState = craft(currentState, (draft) => { // Mutate draft as you like draft.count++; draft.user.name = "Bob"; }); ``` -------------------------------- ### Handle Set Operations (TypeScript) Source: https://context7.com/sylphxltd/craft/llms.txt Craft supports ES6 Set mutations with automatic tracking. Imports needed from @sylphx/craft, manipulates Set objects in state. Allows adding/deleting elements, outputting the updated Set state. ```typescript import { craft } from "@sylphx/craft"; interface State { tags: Set; activeIds: Set; } const state: State = { tags: new Set(["javascript", "typescript"]), activeIds: new Set([1, 2, 3]) }; const next = craft(state, (draft) => { // Add elements draft.tags.add("react"); draft.tags.add("node"); // Delete elements draft.tags.delete("javascript"); // Modify numeric set draft.activeIds.add(4); draft.activeIds.delete(1); }); console.log(Array.from(next.tags)); // ["typescript", "react", "node"] console.log(Array.from(next.activeIds)); // [2, 3, 4] console.log(next.tags.has("javascript")); // false console.log(next.activeIds.has(4)); // true ``` -------------------------------- ### Handle Map Operations (TypeScript) Source: https://context7.com/sylphxltd/craft/llms.txt Craft provides full support for ES6 Map mutations with automatic tracking. Imports from @sylphx/craft, operates on Map objects in state. Supports add, delete, modify, and update operations, outputting the mutated state. ```typescript import { craft } from "@sylphx/craft"; interface State { users: Map; metadata: Map; } const state: State = { users: new Map([ ["alice", { name: "Alice", age: 25 }], ["bob", { name: "Bob", age: 30 }] ]), metadata: new Map([["version", 1]]) }; const next = craft(state, (draft) => { // Add new entry draft.users.set("charlie", { name: "Charlie", age: 35 }); // Delete entry draft.users.delete("alice"); // Modify nested value const bob = draft.users.get("bob"); if (bob) { bob.age = 31; } // Update metadata draft.metadata.set("version", 2); draft.metadata.set("lastUpdate", Date.now()); }); console.log(next.users.size); // 2 console.log(next.users.get("bob")?.age); // 31 console.log(next.users.has("alice")); // false console.log(next.metadata.get("version")); // 2 ``` -------------------------------- ### Compose multiple producers with compose utility Source: https://context7.com/sylphxltd/craft/llms.txt The compose function combines multiple producer functions into a single producer that applies all changes in sequence. This enables functional composition patterns and allows building complex state transformations from simple, reusable producer functions. ```typescript import { craft, compose } from "@sylphx/craft"; interface State { count: number; name: string; active: boolean; } const increment = (draft: State) => { draft.count++; }; const activate = (draft: State) => { draft.active = true; }; const rename = (draft: State) => { draft.name = "Bob"; }; const baseState = { count: 0, name: "Alice", active: false }; // Apply all producers at once const nextState = craft(baseState, compose(increment, activate, rename)); console.log(nextState); // { count: 1, name: "Bob", active: true } ``` -------------------------------- ### Generate Patches with craftWithPatches in TypeScript Source: https://context7.com/sylphxltd/craft/llms.txt craftWithPatches produces a new state, forward patches, and inverse patches from a draft mutation, enabling undo/redo and sync features. It depends on the @sylphx/craft import and works with any mutable draft object. Inputs are base state and a producer function; outputs are next state, patches array, and inverse patches array; limitations include potential performance overhead for deep objects. ```typescript import { craftWithPatches, applyPatches } from "@sylphx/craft"; interface State { count: number; user: { name: string }; items: Array<{ id: number }>; } const state: State = { count: 0, user: { name: "Alice" }, items: [{ id: 1 }, { id: 2 }] }; // Generate state and patches const [nextState, patches, inversePatches] = craftWithPatches(state, (draft) => { draft.count = 5; draft.user.name = "Bob"; draft.items.push({ id: 3 }); }); console.log(patches); // [ // { op: 'replace', path: ['count'], value: 5 }, // { op: 'replace', path: ['user', 'name'], value: 'Bob' }, // { op: 'add', path: ['items', 2], value: { id: 3 } } // ] console.log(inversePatches); // [ // { op: 'replace', path: ['count'], value: 0 }, // { op: 'replace', path: ['user', 'name'], value: 'Alice' }, // { op: 'remove', path: ['items', 2] } // ] // Recreate state from patches const recreated = applyPatches(state, patches); console.log(JSON.stringify(recreated) === JSON.stringify(nextState)); // true // Undo changes with inverse patches const reverted = applyPatches(nextState, inversePatches); console.log(JSON.stringify(reverted) === JSON.stringify(state)); // true ``` -------------------------------- ### Craft function returning new value directly Source: https://github.com/sylphxltd/craft/blob/main/README.md Shows that a producer can return a completely new object instead of mutating the draft, allowing explicit state replacement. ```TypeScript const nextState = craft(currentState, (draft) => { return { ...draft, count: 100 }; }); ``` -------------------------------- ### Control Automatic Freezing (TypeScript) Source: https://github.com/sylphxltd/craft/blob/main/README.md Shows how to configure the automatic freezing of state results using the `setAutoFreeze` function. Disabling auto-freeze can offer performance benefits in scenarios where freezing is not strictly necessary. ```typescript import { setAutoFreeze } from "@sylphx/craft"; // Disable auto-freeze for performance setAutoFreeze(false); ``` -------------------------------- ### Create reusable updaters with crafted function Source: https://context7.com/sylphxltd/craft/llms.txt The crafted function creates reusable updater functions by currying the craft function. These updaters can be applied to different states and composed together. This approach promotes functional programming patterns and code reusability. ```typescript import { crafted } from "@sylphx/craft"; interface State { count: number; name: string; } // Create reusable updaters const increment = crafted((draft: State) => { draft.count++; }); const setName = crafted((draft: State) => { draft.name = "Bob"; }); // Apply updaters to different states const state1 = { count: 0, name: "Alice" }; const state2 = increment(state1); // { count: 1, name: "Alice" } const state3 = increment(state2); // { count: 2, name: "Alice" } const state4 = setName(state3); // { count: 2, name: "Bob" } console.log(state1); // { count: 0, name: "Alice" } console.log(state4); // { count: 2, name: "Bob" } ``` -------------------------------- ### Delete Properties/Elements using `nothing` (TypeScript) Source: https://github.com/sylphxltd/craft/blob/main/README.md Demonstrates the use of the `nothing` symbol in Craft to effectively delete object properties or remove elements from arrays. This provides a clear and concise way to handle removals within the draft state. ```typescript import { craft, nothing } from "@sylphx/craft"; // Delete object property const next = craft(state, (draft) => { draft.obsoleteField = nothing; }); // Remove array elements const next = craft(state, (draft) => { draft.items[2] = nothing; // Remove 3rd element }); // Remove multiple array elements const next = craft(state, (draft) => { draft.todos.forEach((todo, i) => { if (todo.done) { draft.todos[i] = nothing; // Remove completed todos } }); }); ``` -------------------------------- ### TypeScript Type Casting Utilities (TypeScript) Source: https://github.com/sylphxltd/craft/blob/main/README.md Introduces TypeScript utility functions `castDraft` and `castImmutable` for type casting between draft and immutable states. These are primarily for type safety and do not perform runtime conversions. ```typescript import { castDraft, castImmutable } from "@sylphx/craft"; // Cast immutable to draft (type-only) const draft = castDraft(immutableState); // Cast mutable to immutable (type-only) const immutable = castImmutable(mutableState); ``` -------------------------------- ### Reusable updater with crafted Source: https://github.com/sylphxltd/craft/blob/main/README.md Creates a curried updater function using `crafted` that can be applied repeatedly to different state objects. ```TypeScript const increment = crafted((draft: State) => { draft.count++; }); const state1 = { count: 0 }; const state2 = increment(state1); // { count: 1 } const state3 = increment(state2); // { count: 2 } ``` -------------------------------- ### Retrieve original value from draft with original Source: https://github.com/sylphxltd/craft/blob/main/README.md Shows how to obtain the original immutable value underlying a draft using the `original` utility, useful for comparisons. ```TypeScript craft(state, (draft => { draft.count = 10; console.log(draft.count); // 10 (current) console.log(original(draft)?.count); // 0 (original) }); ``` -------------------------------- ### Create immutable state with craft function Source: https://context7.com/sylphxltd/craft/llms.txt The craft function applies mutations to a draft state and returns a new immutable state. It maintains structural sharing for performance by only copying changed parts of the state tree. The base state remains unchanged after the operation. ```typescript import { craft } from "@sylphx/craft"; const baseState = { user: { name: "Alice", age: 25 }, todos: [ { id: 1, text: "Learn Craft", done: false }, { id: 2, text: "Use Craft", done: false } ] }; // Apply mutations to create new state const nextState = craft(baseState, (draft) => { draft.user.age = 26; draft.todos[0].done = true; draft.todos.push({ id: 3, text: "Master Craft", done: false }); }); // Original state unchanged console.log(baseState.user.age); // 25 console.log(baseState.todos.length); // 2 // New state has updates console.log(nextState.user.age); // 26 console.log(nextState.todos.length); // 3 // Structural sharing - unchanged references preserved console.log(baseState.todos[1] === nextState.todos[1]); // true ``` -------------------------------- ### Set Use Strict Shallow Copy (TypeScript) Source: https://context7.com/sylphxltd/craft/llms.txt This function enables strict shallow copying, including non-enumerable properties during state updates. It utilizes the `craft` function from `@sylphx/craft` to perform immutable updates, demonstrating the impact of strict mode on property visibility. ```typescript import { setUseStrictShallowCopy, craft } from "@sylphx/craft"; const state = { count: 0 }; Object.defineProperty(state, "hidden", { value: "secret", enumerable: false }); // Standard mode (default) - ignores non-enumerable setUseStrictShallowCopy(false); const next1 = craft(state, (draft) => { draft.count++; }); console.log((next1 as any).hidden); // undefined // Strict mode - copies non-enumerable properties setUseStrictShallowCopy(true); const next2 = craft(state, (draft) => { draft.count++; }); console.log((next2 as any).hidden); // "secret" ``` -------------------------------- ### Manual draft control with createDraft/finishDraft Source: https://context7.com/sylphxltd/craft/llms.txt Use createDraft and finishDraft for advanced scenarios requiring manual control over the draft lifecycle, such as async operations. This pattern allows making both synchronous and asynchronous changes to a draft before finalizing it into an immutable state. ```typescript import { createDraft, finishDraft } from "@sylphx/craft"; interface AppState { user: { name: string; email: string } | null; count: number; loading: boolean; } const state: AppState = { user: null, count: 0, loading: false }; async function updateWithAPI(baseState: AppState) { const draft = createDraft(baseState); // Make synchronous changes draft.loading = true; draft.count++; // Make async changes const userData = await fetch("/api/user").then(r => r.json()); draft.user = userData; draft.loading = false; // Finalize when ready return finishDraft(draft); } // Usage const nextState = await updateWithAPI(state); console.log(nextState.user); // { name: "Alice", email: "alice@example.com" } console.log(nextState.count); // 1 console.log(nextState.loading); // false ``` -------------------------------- ### Type Safety in Craft State Updates Source: https://github.com/sylphxltd/craft/blob/main/README.md Illustrates Craft's full TypeScript inference for state interfaces, preventing invalid assignments like string to number or accessing nonexistent properties. Inputs are typed state objects; outputs are immutable updates with compile-time checks. Depends on TypeScript; no runtime overhead for types. ```typescript interface State { count: number; user: { name: string; age: number; }; } const state: State = { count: 0, user: { name: "Alice", age: 25 } }; craft(state, (draft) => { draft.count = "invalid"; // ❌ Type error draft.user.age = 26; // ✅ OK draft.nonexistent = true; // ❌ Type error }); ``` -------------------------------- ### Access Original Value with original (TypeScript) Source: https://context7.com/sylphxltd/craft/llms.txt The original function accesses the original base value from within a producer function. It requires importing from @sylphx/craft and is used inside a craft producer. Returns the original state object for comparison or storage, with no access outside producers. ```typescript import { craft, original } from "@sylphx/craft"; interface State { count: number; lastValue: number; } const state: State = { count: 10, lastValue: 0 }; const next = craft(state, (draft) => { const baseValue = original(draft); // Store previous value before updating if (baseValue) { draft.lastValue = baseValue.count; } draft.count = 20; }); console.log(next); // { count: 20, lastValue: 10 } ``` -------------------------------- ### Use Strict Shallow Copy (TypeScript) Source: https://github.com/sylphxltd/craft/blob/main/README.md Enables strict shallow copy behavior with `setUseStrictShallowCopy`. When enabled, it ensures that non-enumerable properties are included during shallow copies, potentially affecting how state is duplicated. ```typescript import { setUseStrictShallowCopy } from "@sylphx/craft"; setUseStrictShallowCopy(true); ``` -------------------------------- ### Manually Freeze Object (TypeScript) Source: https://github.com/sylphxltd/craft/blob/main/README.md Provides a utility function `freeze` to manually freeze an object, either shallowly or deeply. This can be used to ensure immutability for specific objects outside of the standard Craft production process. ```typescript import { freeze } from "@sylphx/craft"; const frozen = freeze(myObject); const deepFrozen = freeze(myObject, true); ``` -------------------------------- ### Configure Auto-Freezing with setAutoFreeze in TypeScript Source: https://context7.com/sylphxltd/craft/llms.txt setAutoFreeze toggles automatic Object.freeze on produced states for immutability in development vs performance in production. Imported from @sylphx/craft, it takes a boolean; affects subsequent craft calls; no direct inputs/outputs but impacts state mutability; limitation is global setting affecting all uses. ```typescript import { setAutoFreeze, craft } from "@sylphx/craft"; // Disable auto-freeze for performance in production setAutoFreeze(false); const state = { count: 0 }; const next = craft(state, (draft) => { draft.count++; }); console.log(Object.isFrozen(next)); // false // Re-enable for development debugging setAutoFreeze(true); const next2 = craft(next, (draft) => { draft.count++; }); console.log(Object.isFrozen(next2)); // true ``` -------------------------------- ### Check Draft Proxy with isDraft (TypeScript) Source: https://context7.com/sylphxltd/craft/llms.txt The isDraft function checks if a value is a draft proxy created by the Craft library. It imports from @sylphx/craft and takes any value as input. Returns a boolean indicating if it's a draft, but cannot detect drafts on primitive values. ```typescript import { craft, isDraft } from "@sylphx/craft"; const state = { count: 0 }; console.log(isDraft(state)); // false craft(state, (draft) => { console.log(isDraft(draft)); // true console.log(isDraft(draft.count)); // false (primitives are not drafts) }); ``` -------------------------------- ### Freeze Object (TypeScript) Source: https://context7.com/sylphxltd/craft/llms.txt This function freezes an object, either shallowly or deeply, to ensure immutability. It uses `Object.isFrozen` to verify the freezing status and demonstrates the difference between shallow and deep freezing for nested objects. ```typescript import { freeze } from "@sylphx/craft"; const mutableState = { user: { name: "Alice", age: 25 }, items: [1, 2, 3] }; // Shallow freeze const shallowFrozen = freeze(mutableState); console.log(Object.isFrozen(shallowFrozen)); // true console.log(Object.isFrozen(shallowFrozen.user)); // false // Deep freeze const deepFrozen = freeze({ ...mutableState }, true); console.log(Object.isFrozen(deepFrozen)); // true console.log(Object.isFrozen(deepFrozen.user)); // true console.log(Object.isFrozen(deepFrozen.items)); // true ``` -------------------------------- ### Check draft status with isDraft Source: https://github.com/sylphxltd/craft/blob/main/README.md Uses the `isDraft` utility to determine whether a given value is a draft created by Craft. ```TypeScript import { craft, isDraft } from "@sylphx/craft"; craft(state, (draft) => { console.log(isDraft(draft)); // true console.log(isDraft(state)); // false }); ``` -------------------------------- ### Delete Properties with nothing Symbol in TypeScript Source: https://context7.com/sylphxltd/craft/llms.txt The nothing symbol, used with craft, removes object properties or array elements without leaving undefined values. Imported from @sylphx/craft, it takes a base state and draft mutator; inputs are state and producer function assigning nothing; outputs a cleaned state; ideal for deletions but requires type assertion as any. ```typescript import { craft, nothing } from "@sylphx/craft"; interface State { name: string; obsoleteField?: string; items: string[]; todos: Array<{ id: number; text: string; done: boolean }>; } const state: State = { name: "App", obsoleteField: "old data", items: ["a", "b", "c", "d"], todos: [ { id: 1, text: "Buy milk", done: true }, { id: 2, text: "Write code", done: false }, { id: 3, text: "Deploy", done: true } ] }; // Delete object properties const next1 = craft(state, (draft) => { draft.obsoleteField = nothing as any; }); console.log("obsoleteField" in next1); // false // Remove specific array elements const next2 = craft(state, (draft) => { draft.items[1] = nothing as any; // Remove "b" }); console.log(next2.items); // ["a", "c", "d"] // Remove completed todos const next3 = craft(state, (draft) => { draft.todos.forEach((todo, index) => { if (todo.done) { draft.todos[index] = nothing as any; } }); }); console.log(next3.todos); // [{ id: 2, text: "Write code", done: false }] ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.