@synapseone/sdk 0.0.0-stage → 0.7.0-dev.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/base.d.ts ADDED
@@ -0,0 +1,253 @@
1
+ import { HttpClient } from './_http';
2
+ export type BaseMappingType = 'string' | 'number' | 'boolean' | 'date' | 'array' | 'object' | 'vector' | 'any';
3
+ export type BaseVectorMetric = 'cosine' | 'l2' | 'ip';
4
+ export interface BaseMappingField {
5
+ /** Dot path inside the stored document. */
6
+ path: string;
7
+ /** Validation type (default: any). */
8
+ type?: BaseMappingType;
9
+ /** Required on full writes (create/replace), not on partial patches. */
10
+ required?: boolean;
11
+ /** Vector dimension (optional, verified if provided). */
12
+ dimension?: number;
13
+ /** Distance metric for similarity queries (default: cosine). */
14
+ metric?: BaseVectorMetric;
15
+ }
16
+ export interface BaseMapping {
17
+ /** Allow logical keys that are not declared in `fields` (default: false). */
18
+ additional?: boolean;
19
+ fields: Record<string, BaseMappingField>;
20
+ }
21
+ /** Canonical `{fields: ...}` mapping or the shorthand `{logical: 'dot.path'}` form. */
22
+ export type BaseMappingInput = BaseMapping | Record<string, string | BaseMappingField>;
23
+ export type BaseQueryOp = 'eq' | 'ne' | 'gt' | 'gte' | 'lt' | 'lte' | 'in' | 'nin' | 'contains' | 'startsWith' | 'endsWith' | 'exists';
24
+ export interface BaseFilter {
25
+ field?: string;
26
+ op?: BaseQueryOp;
27
+ value?: unknown;
28
+ and?: BaseFilter[];
29
+ or?: BaseFilter[];
30
+ not?: BaseFilter;
31
+ }
32
+ export interface BaseOrderBy {
33
+ field: string;
34
+ direction?: 'asc' | 'desc';
35
+ }
36
+ export interface BaseQuery {
37
+ where?: BaseFilter | BaseFilter[] | Record<string, unknown>;
38
+ orderBy?: BaseOrderBy | string | Array<BaseOrderBy | string>;
39
+ limit?: number;
40
+ offset?: number;
41
+ cursor?: string;
42
+ select?: string[];
43
+ as?: 'data' | 'object';
44
+ }
45
+ export interface BaseDocument<T = Record<string, unknown>> {
46
+ id: string;
47
+ data?: T;
48
+ object?: T;
49
+ version: number;
50
+ createdAt: string;
51
+ updatedAt: string;
52
+ collection?: string;
53
+ }
54
+ export interface BaseCollectionInfo {
55
+ id: string;
56
+ name: string;
57
+ description?: string;
58
+ mapping?: BaseMapping;
59
+ orgId?: string;
60
+ accountId?: string;
61
+ createdAt: string;
62
+ updatedAt: string;
63
+ stats?: Record<string, unknown>;
64
+ }
65
+ export interface BaseQueryResult<T = Record<string, unknown>> {
66
+ items: T[];
67
+ total: number;
68
+ limit: number;
69
+ offset: number;
70
+ nextCursor: string | null;
71
+ }
72
+ export interface BaseVectorSearchOptions {
73
+ vector: number[];
74
+ limit?: number;
75
+ k?: number;
76
+ field?: string;
77
+ metric?: BaseVectorMetric;
78
+ where?: BaseFilter | BaseFilter[] | Record<string, unknown>;
79
+ filter?: BaseFilter | BaseFilter[] | Record<string, unknown>;
80
+ select?: string[];
81
+ as?: 'data' | 'object';
82
+ }
83
+ export interface BaseVectorSearchItem<T = Record<string, unknown>> {
84
+ id: string;
85
+ similarity: number;
86
+ distance: number;
87
+ version: number;
88
+ createdAt: string;
89
+ updatedAt: string;
90
+ data?: T;
91
+ object?: T;
92
+ }
93
+ export interface BaseVectorSearchResult<T = Record<string, unknown>> {
94
+ items: BaseVectorSearchItem<T>[];
95
+ total: number;
96
+ limit: number;
97
+ metric: string;
98
+ }
99
+ export declare function normalizeMapping(input?: BaseMappingInput | null): Record<string, BaseMappingField>;
100
+ /** Project stored `data` onto logical field names (empty mapping = copy). */
101
+ export declare function dataToObject(data: Record<string, unknown> | null | undefined, mapping?: BaseMappingInput | null): Record<string, unknown>;
102
+ /** Project a logical object onto stored `data` (empty mapping = copy). */
103
+ export declare function objectToData(obj: Record<string, unknown> | null | undefined, mapping?: BaseMappingInput | null): Record<string, unknown>;
104
+ export declare class BaseService {
105
+ private readonly http;
106
+ constructor(http: HttpClient);
107
+ /** Bind a collection name (plus optional model/mapping) for typed use. */
108
+ collection<T = Record<string, unknown>>(name: string, opts?: BaseCollectionOptions<T>): BaseCollection<T>;
109
+ listCollections(query?: {
110
+ orgId?: string;
111
+ accountId?: string;
112
+ }): Promise<BaseCollectionInfo[]>;
113
+ createCollection(input: {
114
+ name: string;
115
+ description?: string;
116
+ mapping?: BaseMappingInput;
117
+ orgId?: string;
118
+ accountId?: string;
119
+ }): Promise<BaseCollectionInfo>;
120
+ getCollection(name: string): Promise<BaseCollectionInfo>;
121
+ updateCollection(name: string, patch: {
122
+ name?: string;
123
+ description?: string | null;
124
+ mapping?: BaseMappingInput;
125
+ }): Promise<BaseCollectionInfo>;
126
+ deleteCollection(name: string): Promise<{
127
+ ok: boolean;
128
+ id: string;
129
+ name: string;
130
+ }>;
131
+ collectionStats(name: string): Promise<unknown>;
132
+ createDocument<T = Record<string, unknown>>(collection: string, body: {
133
+ data?: Record<string, unknown>;
134
+ object?: T;
135
+ id?: string;
136
+ }): Promise<BaseDocument<T>>;
137
+ getDocument<T = Record<string, unknown>>(collection: string, id: string, query?: {
138
+ as?: 'data' | 'object';
139
+ }): Promise<BaseDocument<T>>;
140
+ setDocument<T = Record<string, unknown>>(collection: string, id: string, body: {
141
+ data?: Record<string, unknown>;
142
+ object?: T;
143
+ ifVersion?: number;
144
+ merge?: boolean;
145
+ }): Promise<BaseDocument<T>>;
146
+ updateDocument<T = Record<string, unknown>>(collection: string, id: string, body: {
147
+ data?: Record<string, unknown>;
148
+ object?: T;
149
+ unset?: string[];
150
+ ifVersion?: number;
151
+ }): Promise<BaseDocument<T>>;
152
+ deleteDocument(collection: string, id: string, opts?: {
153
+ ifVersion?: number;
154
+ }): Promise<{
155
+ ok: boolean;
156
+ id: string;
157
+ }>;
158
+ queryDocuments<T = Record<string, unknown>>(collection: string, query?: BaseQuery): Promise<BaseQueryResult<T>>;
159
+ vectorSearch<T = Record<string, unknown>>(collection: string, options: BaseVectorSearchOptions): Promise<BaseVectorSearchResult<T>>;
160
+ listDocuments<T = Record<string, unknown>>(collection: string, opts?: {
161
+ limit?: number;
162
+ offset?: number;
163
+ }): Promise<Array<BaseDocument<T>>>;
164
+ increment<T = Record<string, unknown>>(collection: string, id: string, body: {
165
+ field: string;
166
+ by?: number;
167
+ ifVersion?: number;
168
+ }): Promise<BaseDocument<T>>;
169
+ batch(collection: string, operations: Record<string, unknown>[]): Promise<{
170
+ results: any[];
171
+ ok: boolean;
172
+ }>;
173
+ changes<T = Record<string, unknown>>(collection: string, query: {
174
+ since: string;
175
+ limit?: number;
176
+ as?: 'data' | 'object';
177
+ }): Promise<{
178
+ changes: any[];
179
+ nextSince: string;
180
+ hasMore: boolean;
181
+ }>;
182
+ }
183
+ export interface BaseCollectionOptions<T> {
184
+ /** Optional factory turning a logical object into your model instance. */
185
+ model?: (obj: Record<string, unknown>) => T;
186
+ /** Server-side mapping (logical -> dot path), used for data responses. */
187
+ mapping?: BaseMappingInput;
188
+ }
189
+ /**
190
+ * A collection bound to a service, with optional model factory + mapping.
191
+ *
192
+ * Typed methods send logical `object` payloads; raw `data` writes are available
193
+ * through the `data` option. Reads use `as: 'object'` and run through the model
194
+ * factory, while endpoints that return raw `data` (list/increment/changes) are
195
+ * converted locally with the mapping.
196
+ */
197
+ export declare class BaseCollection<T = Record<string, unknown>> {
198
+ private readonly service;
199
+ readonly name: string;
200
+ private readonly opts;
201
+ constructor(service: BaseService, name: string, opts?: BaseCollectionOptions<T>);
202
+ toObject(value: T): Record<string, unknown>;
203
+ fromObject(obj: Record<string, unknown> | null | undefined): T;
204
+ fromData(data: Record<string, unknown> | null | undefined): T;
205
+ private docResult;
206
+ create(value?: T, opts?: {
207
+ id?: string;
208
+ data?: Record<string, unknown>;
209
+ }): Promise<T>;
210
+ get(id: string): Promise<T>;
211
+ getDocument(id: string, as?: 'data' | 'object'): Promise<BaseDocument<any>>;
212
+ list(opts?: {
213
+ limit?: number;
214
+ offset?: number;
215
+ }): Promise<T[]>;
216
+ set(id: string, value?: T, opts?: {
217
+ data?: Record<string, unknown>;
218
+ ifVersion?: number;
219
+ merge?: boolean;
220
+ }): Promise<T>;
221
+ update(id: string, value?: T, opts?: {
222
+ data?: Record<string, unknown>;
223
+ unset?: string[];
224
+ ifVersion?: number;
225
+ }): Promise<T>;
226
+ delete(id: string, opts?: {
227
+ ifVersion?: number;
228
+ }): Promise<{
229
+ ok: boolean;
230
+ id: string;
231
+ }>;
232
+ increment(id: string, body: {
233
+ field: string;
234
+ by?: number;
235
+ ifVersion?: number;
236
+ }): Promise<T>;
237
+ query(query?: BaseQuery): Promise<BaseQueryResult<T>>;
238
+ vectorSearch(options: Omit<BaseVectorSearchOptions, 'as'>): Promise<BaseVectorSearchResult<T>>;
239
+ changes(query: {
240
+ since: string;
241
+ limit?: number;
242
+ }): Promise<{
243
+ changes: any[];
244
+ nextSince: string;
245
+ hasMore: boolean;
246
+ }>;
247
+ batch(operations: Record<string, unknown>[]): Promise<{
248
+ results: any[];
249
+ ok: boolean;
250
+ }>;
251
+ stats(): Promise<unknown>;
252
+ private writeInput;
253
+ }
package/dist/base.js ADDED
@@ -0,0 +1,339 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright 2026 SynapseOne Contributors
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * SynapseBase client: collections, documents, queries, batch writes, atomic
6
+ * counters, the change feed and typed object<->data mapping.
7
+ *
8
+ * The service stores raw JSON `data`; a collection may declare a mapping from
9
+ * logical field names to dot paths inside that data. Writes can send `object`
10
+ * (logical keys) and reads can ask `as: 'object'` — the service converts in
11
+ * both directions. `BaseCollection` is a typed wrapper for one collection.
12
+ */
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.BaseCollection = exports.BaseService = void 0;
15
+ exports.normalizeMapping = normalizeMapping;
16
+ exports.dataToObject = dataToObject;
17
+ exports.objectToData = objectToData;
18
+ const _UNSET = Symbol('unset');
19
+ // ---------------------------------------------------------------------------
20
+ // mapping helpers (client-side mirror of the server object<->data mapping)
21
+ // ---------------------------------------------------------------------------
22
+ function normalizeMapping(input) {
23
+ if (!input)
24
+ return {};
25
+ const raw = input.fields && typeof input.fields === 'object'
26
+ ? input.fields
27
+ : input;
28
+ const out = {};
29
+ for (const [name, spec] of Object.entries(raw)) {
30
+ if (typeof spec === 'string')
31
+ out[name] = { path: spec };
32
+ else if (spec && typeof spec === 'object')
33
+ out[name] = { ...spec };
34
+ }
35
+ return out;
36
+ }
37
+ function getPath(data, path) {
38
+ let cur = data;
39
+ for (const key of String(path).split('.')) {
40
+ if (!cur || typeof cur !== 'object' || !(key in cur))
41
+ return _UNSET;
42
+ cur = cur[key];
43
+ }
44
+ return cur;
45
+ }
46
+ function setPath(target, path, value) {
47
+ const segments = String(path).split('.');
48
+ let cur = target;
49
+ for (const key of segments.slice(0, -1)) {
50
+ if (!cur[key] || typeof cur[key] !== 'object' || Array.isArray(cur[key]))
51
+ cur[key] = {};
52
+ cur = cur[key];
53
+ }
54
+ cur[segments[segments.length - 1]] = value;
55
+ }
56
+ /** Project stored `data` onto logical field names (empty mapping = copy). */
57
+ function dataToObject(data, mapping) {
58
+ const fields = normalizeMapping(mapping);
59
+ if (!Object.keys(fields).length)
60
+ return { ...(data || {}) };
61
+ const out = {};
62
+ for (const [name, spec] of Object.entries(fields)) {
63
+ const value = getPath(data || {}, spec.path);
64
+ if (value !== _UNSET)
65
+ out[name] = value;
66
+ }
67
+ return out;
68
+ }
69
+ /** Project a logical object onto stored `data` (empty mapping = copy). */
70
+ function objectToData(obj, mapping) {
71
+ const fields = normalizeMapping(mapping);
72
+ const out = {};
73
+ for (const [key, value] of Object.entries(obj || {})) {
74
+ setPath(out, fields[key] ? fields[key].path : key, value);
75
+ }
76
+ return out;
77
+ }
78
+ function writeBody(body) {
79
+ const hasData = body.data !== undefined;
80
+ const hasObject = body.object !== undefined;
81
+ if (hasData === hasObject)
82
+ throw new Error('provide exactly one of data or object');
83
+ return hasData ? { data: body.data } : { object: body.object };
84
+ }
85
+ function queryString(params) {
86
+ const p = new URLSearchParams();
87
+ for (const [k, v] of Object.entries(params)) {
88
+ if (v !== undefined && v !== null && String(v) !== '')
89
+ p.set(k, String(v));
90
+ }
91
+ const s = p.toString();
92
+ return s ? `?${s}` : '';
93
+ }
94
+ // ---------------------------------------------------------------------------
95
+ // service
96
+ // ---------------------------------------------------------------------------
97
+ class BaseService {
98
+ http;
99
+ constructor(http) {
100
+ this.http = http;
101
+ }
102
+ /** Bind a collection name (plus optional model/mapping) for typed use. */
103
+ collection(name, opts = {}) {
104
+ return new BaseCollection(this, name, opts);
105
+ }
106
+ // ---- collections ----
107
+ listCollections(query = {}) {
108
+ return this.http.req(`/v1/base/collections${queryString({ orgId: query.orgId, accountId: query.accountId })}`);
109
+ }
110
+ createCollection(input) {
111
+ return this.http.req('/v1/base/collections', { method: 'POST', body: JSON.stringify(input) });
112
+ }
113
+ getCollection(name) {
114
+ return this.http.req(`/v1/base/collections/${encodeURIComponent(name)}`);
115
+ }
116
+ updateCollection(name, patch) {
117
+ return this.http.req(`/v1/base/collections/${encodeURIComponent(name)}`, { method: 'PATCH', body: JSON.stringify(patch) });
118
+ }
119
+ deleteCollection(name) {
120
+ return this.http.req(`/v1/base/collections/${encodeURIComponent(name)}`, { method: 'DELETE' });
121
+ }
122
+ collectionStats(name) {
123
+ return this.http.req(`/v1/base/collections/${encodeURIComponent(name)}/stats`);
124
+ }
125
+ // ---- documents ----
126
+ createDocument(collection, body) {
127
+ return this.http.req(`/v1/base/collections/${encodeURIComponent(collection)}/documents`, {
128
+ method: 'POST',
129
+ body: JSON.stringify({ ...writeBody(body), ...(body.id !== undefined ? { id: body.id } : {}) }),
130
+ });
131
+ }
132
+ getDocument(collection, id, query = {}) {
133
+ return this.http.req(`/v1/base/collections/${encodeURIComponent(collection)}/documents/${encodeURIComponent(id)}${queryString({ as: query.as })}`);
134
+ }
135
+ setDocument(collection, id, body) {
136
+ return this.http.req(`/v1/base/collections/${encodeURIComponent(collection)}/documents/${encodeURIComponent(id)}`, {
137
+ method: 'PUT',
138
+ body: JSON.stringify({
139
+ ...writeBody(body),
140
+ ...(body.ifVersion !== undefined ? { ifVersion: body.ifVersion } : {}),
141
+ ...(body.merge ? { merge: true } : {}),
142
+ }),
143
+ });
144
+ }
145
+ updateDocument(collection, id, body) {
146
+ if (body.data === undefined && body.object === undefined && !body.unset?.length) {
147
+ throw new Error('provide data/object and/or unset');
148
+ }
149
+ const payload = {};
150
+ if (body.data !== undefined || body.object !== undefined)
151
+ Object.assign(payload, writeBody(body));
152
+ if (body.unset?.length)
153
+ payload.unset = body.unset;
154
+ if (body.ifVersion !== undefined)
155
+ payload.ifVersion = body.ifVersion;
156
+ return this.http.req(`/v1/base/collections/${encodeURIComponent(collection)}/documents/${encodeURIComponent(id)}`, {
157
+ method: 'PATCH', body: JSON.stringify(payload),
158
+ });
159
+ }
160
+ deleteDocument(collection, id, opts = {}) {
161
+ return this.http.req(`/v1/base/collections/${encodeURIComponent(collection)}/documents/${encodeURIComponent(id)}${queryString({ ifVersion: opts.ifVersion })}`, { method: 'DELETE' });
162
+ }
163
+ // ---- query / batch / changes ----
164
+ queryDocuments(collection, query = {}) {
165
+ const body = { as: query.as ?? 'data' };
166
+ if (query.where !== undefined)
167
+ body.where = query.where;
168
+ if (query.orderBy !== undefined)
169
+ body.orderBy = query.orderBy;
170
+ if (query.limit !== undefined)
171
+ body.limit = query.limit;
172
+ if (query.offset !== undefined)
173
+ body.offset = query.offset;
174
+ if (query.cursor !== undefined)
175
+ body.cursor = query.cursor;
176
+ if (query.select !== undefined)
177
+ body.select = query.select;
178
+ return this.http.req(`/v1/base/collections/${encodeURIComponent(collection)}/query`, {
179
+ method: 'POST', body: JSON.stringify(body),
180
+ });
181
+ }
182
+ vectorSearch(collection, options) {
183
+ const body = {
184
+ vector: options.vector,
185
+ as: options.as ?? 'data',
186
+ };
187
+ if (options.limit !== undefined)
188
+ body.limit = options.limit;
189
+ if (options.k !== undefined)
190
+ body.k = options.k;
191
+ if (options.field !== undefined)
192
+ body.field = options.field;
193
+ if (options.metric !== undefined)
194
+ body.metric = options.metric;
195
+ if (options.where !== undefined)
196
+ body.where = options.where;
197
+ if (options.filter !== undefined)
198
+ body.filter = options.filter;
199
+ if (options.select !== undefined)
200
+ body.select = options.select;
201
+ return this.http.req(`/v1/base/collections/${encodeURIComponent(collection)}/vector-search`, {
202
+ method: 'POST',
203
+ body: JSON.stringify(body),
204
+ });
205
+ }
206
+ listDocuments(collection, opts = {}) {
207
+ return this.http.req(`/v1/base/collections/${encodeURIComponent(collection)}/documents${queryString({ limit: opts.limit, offset: opts.offset })}`);
208
+ }
209
+ increment(collection, id, body) {
210
+ return this.http.req(`/v1/base/collections/${encodeURIComponent(collection)}/documents/${encodeURIComponent(id)}/increment`, {
211
+ method: 'POST',
212
+ body: JSON.stringify({
213
+ field: body.field,
214
+ by: body.by ?? 1,
215
+ ...(body.ifVersion !== undefined ? { ifVersion: body.ifVersion } : {}),
216
+ }),
217
+ });
218
+ }
219
+ batch(collection, operations) {
220
+ return this.http.req(`/v1/base/collections/${encodeURIComponent(collection)}/documents:batch`, { method: 'POST', body: JSON.stringify({ operations }) });
221
+ }
222
+ changes(collection, query) {
223
+ return this.http.req(`/v1/base/collections/${encodeURIComponent(collection)}/changes${queryString({
224
+ since: query.since, limit: query.limit, as: query.as,
225
+ })}`);
226
+ }
227
+ }
228
+ exports.BaseService = BaseService;
229
+ /**
230
+ * A collection bound to a service, with optional model factory + mapping.
231
+ *
232
+ * Typed methods send logical `object` payloads; raw `data` writes are available
233
+ * through the `data` option. Reads use `as: 'object'` and run through the model
234
+ * factory, while endpoints that return raw `data` (list/increment/changes) are
235
+ * converted locally with the mapping.
236
+ */
237
+ class BaseCollection {
238
+ service;
239
+ name;
240
+ opts;
241
+ constructor(service, name, opts = {}) {
242
+ this.service = service;
243
+ this.name = name;
244
+ this.opts = opts;
245
+ }
246
+ toObject(value) {
247
+ return value;
248
+ }
249
+ fromObject(obj) {
250
+ const value = obj ?? {};
251
+ return this.opts.model ? this.opts.model(value) : value;
252
+ }
253
+ fromData(data) {
254
+ return this.fromObject(dataToObject(data, this.opts.mapping));
255
+ }
256
+ docResult(doc) {
257
+ return doc.object !== undefined ? this.fromObject(doc.object) : this.fromData(doc.data);
258
+ }
259
+ create(value, opts = {}) {
260
+ const body = this.writeInput(value, opts.data, 'value');
261
+ return this.service
262
+ .createDocument(this.name, { ...body, id: opts.id })
263
+ .then((doc) => this.docResult(doc));
264
+ }
265
+ get(id) {
266
+ return this.service
267
+ .getDocument(this.name, id, { as: 'object' })
268
+ .then((doc) => this.fromObject(doc.object));
269
+ }
270
+ getDocument(id, as = 'data') {
271
+ return this.service.getDocument(this.name, id, { as });
272
+ }
273
+ list(opts = {}) {
274
+ return this.service
275
+ .listDocuments(this.name, opts)
276
+ .then((docs) => docs.map((doc) => this.fromData(doc.data)));
277
+ }
278
+ set(id, value, opts = {}) {
279
+ const body = this.writeInput(value, opts.data, 'value');
280
+ return this.service
281
+ .setDocument(this.name, id, { ...body, ifVersion: opts.ifVersion, merge: opts.merge })
282
+ .then((doc) => this.docResult(doc));
283
+ }
284
+ update(id, value, opts = {}) {
285
+ const body = {};
286
+ if (value !== undefined || opts.data !== undefined)
287
+ Object.assign(body, this.writeInput(value, opts.data, 'value'));
288
+ else if (!opts.unset?.length)
289
+ throw new Error('provide a value, data or unset');
290
+ return this.service
291
+ .updateDocument(this.name, id, { ...body, unset: opts.unset, ifVersion: opts.ifVersion })
292
+ .then((doc) => this.docResult(doc));
293
+ }
294
+ delete(id, opts = {}) {
295
+ return this.service.deleteDocument(this.name, id, opts);
296
+ }
297
+ increment(id, body) {
298
+ return this.service
299
+ .increment(this.name, id, body)
300
+ .then((doc) => this.fromData(doc.data));
301
+ }
302
+ query(query = {}) {
303
+ return this.service.queryDocuments(this.name, { ...query, as: 'object' }).then((result) => ({
304
+ ...result,
305
+ items: result.items.map((item) => this.fromObject(item.object)),
306
+ }));
307
+ }
308
+ vectorSearch(options) {
309
+ return this.service
310
+ .vectorSearch(this.name, { ...options, as: 'object' })
311
+ .then((result) => ({
312
+ ...result,
313
+ items: result.items.map((item) => ({
314
+ ...item,
315
+ object: this.fromObject(item.object),
316
+ })),
317
+ }));
318
+ }
319
+ changes(query) {
320
+ return this.service.changes(this.name, { ...query, as: 'object' }).then((raw) => ({
321
+ ...raw,
322
+ changes: raw.changes.map((ch) => ({ ...ch, document: this.fromObject(ch.object) })),
323
+ }));
324
+ }
325
+ batch(operations) {
326
+ return this.service.batch(this.name, operations);
327
+ }
328
+ stats() {
329
+ return this.service.collectionStats(this.name);
330
+ }
331
+ writeInput(value, data, name) {
332
+ if (value !== undefined && data !== undefined)
333
+ throw new Error(`provide exactly one of ${name} or data`);
334
+ if (value === undefined && data === undefined)
335
+ throw new Error(`provide exactly one of ${name} or data`);
336
+ return data !== undefined ? { data } : { object: value };
337
+ }
338
+ }
339
+ exports.BaseCollection = BaseCollection;
@@ -0,0 +1 @@
1
+ export {};