/** * The smallest amount of state a mock needs to behave like an API rather than a * fixture dump: a POST that shows up in the following GET. Deliberately not a * database — no queries, no indexes, no relations. A mock that needs those is a * mock standing in for logic the real service owns. */ export type MockStoreOptions = { /** * How an item's identity is read. Defaults to its `id` property, which must be * a string or a number. */ id?: (item: T) => string; }; /** * Aliasing, since it is observable: `get`, `insert`, and the elements of * `list` are the **stored** objects, so mutating one writes through to the * store — only `list`'s array is a copy. `update` replaces the item with * a merged copy instead, which leaves any reference taken before the update * stale. Read again after an update rather than holding a reference across one. */ export type MockStore = { /** * Every item, in insertion order. The array is fresh, so sorting, slicing, or * splicing it cannot reorder the store — but its elements are the stored * objects, not copies, so mutating one writes through like `get` does. */ list: () => T[]; get: (id: string) => T | undefined; has: (id: string) => boolean; readonly size: number; /** Adds an item. Throws on a duplicate id, which is a fixture bug rather than an API condition. */ insert: (item: T) => T; /** * Merges `patch` into an existing item, keeping its position. `undefined` * when the id is unknown — a handler turns that into its own 404. * * A patch may carry the id, which moves the item to it; the old id then * misses. Throws if that id is already taken, like `insert`, and leaves the * store untouched when it does. */ update: (id: string, patch: Partial) => T | undefined; /** `false` when the id is unknown. */ remove: (id: string) => boolean; /** Swaps in a whole collection. Throws if two items share an id, like `insert`. */ replaceAll: (items: readonly T[]) => void; /** Re-seeds from the seed function. Pass this to `setupMocks({ onReset })`. */ reset: () => void; }; /** * An in-memory collection whose `reset` restores the seeded contents. * * The seed is a **function**, called on construction and again on every reset, so * a handler that mutates an item in place cannot corrupt the next test's * starting point. That holds only if the function *constructs* its items — a * seed that returns a shared module-level array hands out the same objects every * time, and a mutation to one of those does survive a reset. * * ```ts * const things = createMockStore(seedThings); * * export const mocks = setupMocks( * [ * mock.get('/things', ({ response }) => response(200).json(things.list())), * mock.get('/things/{id}', ({ params, response }) => { * const thing = things.get(params.id); * * return thing * ? response(200).json(thing) * : response(404).json({ message: 'not found' }); * }), * ], * { onReset: [things.reset] }, * ); * ``` */ export declare function createMockStore(seed: () => readonly T[], options?: MockStoreOptions): MockStore;