@objectql/types 4.1.0 → 4.2.1

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/logger.js ADDED
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ /**
3
+ * ObjectQL - Logger Type Definitions
4
+ * Copyright (c) 2026-present ObjectStack Inc.
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE file in the root directory of this source tree.
8
+ *
9
+ * Defines the canonical Logger interface for the ObjectQL ecosystem.
10
+ * All packages must use this interface instead of direct console.* calls.
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.NullLogger = exports.ConsoleLogger = void 0;
14
+ /**
15
+ * Console-based Logger implementation
16
+ *
17
+ * A zero-dependency reference implementation suitable for:
18
+ * - Unit tests (without mocking an external logger library)
19
+ * - Development environments
20
+ * - Packages that cannot depend on `@objectstack/core`
21
+ *
22
+ * For production use, prefer the structured logger from `@objectstack/core`.
23
+ */
24
+ class ConsoleLogger {
25
+ constructor(config) {
26
+ var _a;
27
+ this.name = config.name;
28
+ this.level = (_a = config.level) !== null && _a !== void 0 ? _a : 'info';
29
+ }
30
+ shouldLog(level) {
31
+ return ConsoleLogger.LEVELS[level] >= ConsoleLogger.LEVELS[this.level];
32
+ }
33
+ format(level, message, data) {
34
+ const ts = new Date().toISOString();
35
+ const prefix = `${ts} [${level.toUpperCase().padEnd(5)}] [${this.name}]`;
36
+ if (data && Object.keys(data).length > 0) {
37
+ return `${prefix} ${message} ${JSON.stringify(data)}`;
38
+ }
39
+ return `${prefix} ${message}`;
40
+ }
41
+ trace(message, data) {
42
+ if (this.shouldLog('trace'))
43
+ console.debug(this.format('trace', message, data));
44
+ }
45
+ debug(message, data) {
46
+ if (this.shouldLog('debug'))
47
+ console.debug(this.format('debug', message, data));
48
+ }
49
+ info(message, data) {
50
+ if (this.shouldLog('info'))
51
+ console.log(this.format('info', message, data));
52
+ }
53
+ warn(message, data) {
54
+ if (this.shouldLog('warn'))
55
+ console.warn(this.format('warn', message, data));
56
+ }
57
+ error(message, error, data) {
58
+ if (this.shouldLog('error')) {
59
+ console.error(this.format('error', message, data));
60
+ if (error === null || error === void 0 ? void 0 : error.stack)
61
+ console.error(error.stack);
62
+ }
63
+ }
64
+ fatal(message, error, data) {
65
+ if (this.shouldLog('fatal')) {
66
+ console.error(this.format('fatal', message, data));
67
+ if (error === null || error === void 0 ? void 0 : error.stack)
68
+ console.error(error.stack);
69
+ }
70
+ }
71
+ }
72
+ exports.ConsoleLogger = ConsoleLogger;
73
+ ConsoleLogger.LEVELS = {
74
+ trace: 0,
75
+ debug: 1,
76
+ info: 2,
77
+ warn: 3,
78
+ error: 4,
79
+ fatal: 5,
80
+ };
81
+ /**
82
+ * No-op Logger implementation
83
+ *
84
+ * Useful for suppressing all log output (e.g., in benchmarks or silent tests).
85
+ */
86
+ class NullLogger {
87
+ trace() { }
88
+ debug() { }
89
+ info() { }
90
+ warn() { }
91
+ error() { }
92
+ fatal() { }
93
+ }
94
+ exports.NullLogger = NullLogger;
95
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"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"}
package/dist/object.d.ts CHANGED
@@ -5,9 +5,25 @@
5
5
  * This source code is licensed under the MIT license found in the
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
+ import { Data, Automation } from '@objectstack/spec';
9
+ import { z } from 'zod';
8
10
  import { FieldConfig } from './field';
9
11
  import { ActionConfig } from './action';
10
12
  import { AnyValidationRule } from './validation';
13
+ import { SyncConfig } from './sync';
14
+ /**
15
+ * Re-export Protocol Types from @objectstack/spec 1.1.0
16
+ * State Machine, Object Ownership, and Object Extension types.
17
+ */
18
+ export type StateMachineConfig = z.infer<typeof Automation.StateMachineSchema>;
19
+ export type StateNodeConfig = z.infer<typeof Automation.StateNodeSchema>;
20
+ export type Transition = z.infer<typeof Automation.TransitionSchema>;
21
+ export type ActionRef = z.infer<typeof Automation.ActionRefSchema>;
22
+ export type ObjectOwnership = z.infer<typeof Data.ObjectOwnershipEnum>;
23
+ export type ObjectExtension = z.infer<typeof Data.ObjectExtensionSchema>;
24
+ export type ServiceObject = z.infer<typeof Data.ObjectSchema>;
25
+ /** Re-export Zod schemas for validation */
26
+ export { Data, Automation };
11
27
  /**
12
28
  * RUNTIME-SPECIFIC TYPES
13
29
  * The following types extend or complement the Protocol Constitution
@@ -104,6 +120,18 @@ export interface ObjectConfig {
104
120
  /**
105
121
  * RUNTIME EXTENSIONS BELOW
106
122
  */
123
+ /**
124
+ * State Machine definition for object lifecycle management.
125
+ * Follows the @objectstack/spec StateMachineConfig protocol.
126
+ * Enables declarative state transitions, guards, and entry/exit actions.
127
+ */
128
+ stateMachine?: StateMachineConfig;
129
+ /**
130
+ * Named state machines for multi-field lifecycle.
131
+ * Each key is a state machine identifier, useful when an object
132
+ * has multiple independent state fields.
133
+ */
134
+ stateMachines?: Record<string, StateMachineConfig>;
107
135
  /** AI capabilities configuration (RUNTIME ONLY) */
108
136
  ai?: ObjectAiConfig;
109
137
  /** Custom actions (RUNTIME ONLY) */
@@ -118,6 +146,19 @@ export interface ObjectConfig {
118
146
  validation_strategy?: string;
119
147
  };
120
148
  };
149
+ /**
150
+ * Offline-First Sync configuration (RUNTIME ONLY).
151
+ * Opt-in per object. See {@link SyncConfig} for details.
152
+ *
153
+ * @example
154
+ * ```yaml
155
+ * sync:
156
+ * enabled: true
157
+ * strategy: last-write-wins
158
+ * conflict_fields: [status]
159
+ * ```
160
+ */
161
+ sync?: SyncConfig;
121
162
  }
122
163
  /**
123
164
  * Base interface for all ObjectQL documents.
@@ -128,5 +169,5 @@ export interface ObjectDoc {
128
169
  _id?: string | number;
129
170
  created_at?: Date | string;
130
171
  updated_at?: Date | string;
131
- [key: string]: any;
172
+ [key: string]: unknown;
132
173
  }
package/dist/object.js CHANGED
@@ -7,4 +7,8 @@
7
7
  * LICENSE file in the root directory of this source tree.
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.Automation = exports.Data = void 0;
11
+ const spec_1 = require("@objectstack/spec");
12
+ Object.defineProperty(exports, "Data", { enumerable: true, get: function () { return spec_1.Data; } });
13
+ Object.defineProperty(exports, "Automation", { enumerable: true, get: function () { return spec_1.Automation; } });
10
14
  //# sourceMappingURL=object.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"object.js","sourceRoot":"","sources":["../src/object.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG"}
1
+ {"version":3,"file":"object.js","sourceRoot":"","sources":["../src/object.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAEH,4CAAqD;AAoB5C,qFApBA,WAAI,OAoBA;AAAE,2FApBA,iBAAU,OAoBA"}
@@ -70,7 +70,7 @@ export interface SimpleCondition {
70
70
  /** Comparison operator */
71
71
  operator: PermissionOperator;
72
72
  /** Value to compare against (can include variables like $current_user.id) */
73
- value: any;
73
+ value: unknown;
74
74
  }
75
75
  /**
76
76
  * Simple condition element (inline form for complex expressions)
@@ -78,7 +78,7 @@ export interface SimpleCondition {
78
78
  export interface ConditionElement {
79
79
  field: string;
80
80
  operator: PermissionOperator;
81
- value: any;
81
+ value: unknown;
82
82
  }
83
83
  /**
84
84
  * Expression element in complex conditions
@@ -208,7 +208,7 @@ export interface ActionCondition {
208
208
  /** Comparison operator */
209
209
  operator: PermissionOperator;
210
210
  /** Value to compare */
211
- value: any;
211
+ value: unknown;
212
212
  }
213
213
  /**
214
214
  * Rate limiting configuration for actions
@@ -372,7 +372,7 @@ export interface PermissionCheckContext {
372
372
  roles?: string[];
373
373
  department_id?: string;
374
374
  team_id?: string;
375
- [key: string]: any;
375
+ [key: string]: unknown;
376
376
  };
377
377
  /** Object name */
378
378
  object: string;
@@ -383,7 +383,7 @@ export interface PermissionCheckContext {
383
383
  /** Field name (for field-level checks) */
384
384
  field?: string;
385
385
  /** Record data (for condition evaluation) */
386
- record?: any;
386
+ record?: Record<string, unknown>;
387
387
  }
388
388
  /**
389
389
  * Result of a permission check
package/dist/plugin.d.ts CHANGED
@@ -21,12 +21,12 @@ export interface RuntimeContext {
21
21
  * - action manager
22
22
  * - CRUD operations
23
23
  */
24
- engine: any;
24
+ engine: unknown;
25
25
  /**
26
26
  * Get the kernel instance (alternative accessor)
27
27
  * Some implementations may use getKernel() instead of engine
28
28
  */
29
- getKernel?: () => any;
29
+ getKernel?: () => unknown;
30
30
  }
31
31
  /**
32
32
  * RuntimePlugin Interface
@@ -78,6 +78,11 @@ export interface RuntimePlugin {
78
78
  * Example: '1.0.0', '2.1.3-beta'
79
79
  */
80
80
  version?: string;
81
+ /**
82
+ * Initialize the plugin
83
+ * Called when the plugin is loaded into the kernel
84
+ */
85
+ init?(ctx: RuntimeContext): Promise<void>;
81
86
  /**
82
87
  * Install hook - called during kernel initialization
83
88
  *
package/dist/query.d.ts CHANGED
@@ -6,22 +6,27 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
  import { Data } from '@objectstack/spec';
9
- type FilterCondition = Data.FilterCondition;
9
+ import { z } from 'zod';
10
+ export type Filter = z.infer<typeof Data.FilterCondition>;
11
+ export type SortNode = z.infer<typeof Data.SortNodeSchema>;
12
+ export type AggregationFunctionType = z.infer<typeof Data.AggregationFunction>;
13
+ export type AggregationNode = z.infer<typeof Data.AggregationNodeSchema>;
10
14
  /**
11
- * Modern Query Filter using @objectstack/spec FilterCondition
12
- *
13
- * Supports MongoDB/Prisma-style object-based syntax:
14
- * - Implicit equality: { field: value }
15
- * - Explicit operators: { field: { $eq: value, $gt: 10 } }
16
- * - Logical operators: { $and: [...], $or: [...] }
17
- * - String operators: { name: { $contains: "text" } }
18
- * - Range operators: { age: { $gte: 18, $lte: 65 } }
19
- * - Set operators: { status: { $in: ["active", "pending"] } }
20
- * - Null checks: { field: { $null: true } }
15
+ * Unified Query Interface - Standard Protocol Format
21
16
  *
22
- * Note: $not operator is not supported. Use $ne for field-level negation.
17
+ * Uses @objectstack/spec QuerySchema inference directly.
18
+ * We make 'object' optional because in many contexts (like Repository.find),
19
+ * the object is implicit.
20
+ */
21
+ type SpecQuery = z.infer<typeof Data.QuerySchema>;
22
+ export interface UnifiedQuery extends Omit<SpecQuery, 'object'> {
23
+ object?: string;
24
+ }
25
+ /**
26
+ * Standard QueryAST definition.
27
+ * Aliased to UnifiedQuery for backward compatibility and consistency.
23
28
  */
24
- export type Filter = FilterCondition;
29
+ export type QueryAST = UnifiedQuery;
25
30
  /** @deprecated Use AggregationFunctionType instead */
26
31
  export type AggregateFunction = AggregationFunctionType;
27
32
  /** @deprecated Use AggregationNode instead */
@@ -30,62 +35,4 @@ export interface AggregateOption {
30
35
  field: string;
31
36
  alias?: string;
32
37
  }
33
- /**
34
- * Sort Node - Standard Protocol Format
35
- * Represents an "Order By" clause.
36
- */
37
- export interface SortNode {
38
- /** Field name to sort by */
39
- field: string;
40
- /** Sort direction - defaults to 'asc' */
41
- order: 'asc' | 'desc';
42
- }
43
- /**
44
- * Aggregation Function - Standard Protocol Format
45
- */
46
- export type AggregationFunctionType = 'count' | 'sum' | 'avg' | 'min' | 'max' | 'count_distinct' | 'array_agg' | 'string_agg';
47
- /**
48
- * Aggregation Node - Standard Protocol Format
49
- * Represents an aggregated field with function.
50
- */
51
- export interface AggregationNode {
52
- /** Aggregation function to apply */
53
- function: AggregationFunctionType;
54
- /** Field to aggregate (optional for count) */
55
- field?: string;
56
- /** Alias for the result field */
57
- alias: string;
58
- /** Apply DISTINCT to the field before aggregation */
59
- distinct?: boolean;
60
- /** Optional filter condition for this aggregation */
61
- filter?: Filter;
62
- }
63
- /**
64
- * Unified Query Interface - Standard Protocol Format
65
- *
66
- * Uses @objectstack/spec QueryAST format directly.
67
- * This is the single source of truth for query structure.
68
- */
69
- export interface UnifiedQuery {
70
- /** Field selection - specify which fields to return */
71
- fields?: string[];
72
- /** Filter conditions using standard FilterCondition syntax (was: filters) */
73
- where?: Filter;
74
- /** Sort order - array of SortNode objects (was: sort as tuples) */
75
- orderBy?: SortNode[];
76
- /** Pagination - number of records to skip (was: skip) */
77
- offset?: number;
78
- /** Pagination - maximum number of records to return */
79
- limit?: number;
80
- /** Relation expansion - load related records */
81
- expand?: Record<string, UnifiedQuery>;
82
- /** Aggregation - group by fields */
83
- groupBy?: string[];
84
- /** Aggregation - aggregate functions to apply (was: aggregate with func) */
85
- aggregations?: AggregationNode[];
86
- /** Filter for aggregated results (HAVING clause) */
87
- having?: Filter;
88
- /** Enable distinct results */
89
- distinct?: boolean;
90
- }
91
38
  export {};
@@ -16,11 +16,11 @@ export declare class MetadataRegistry {
16
16
  private items;
17
17
  private packageIndex;
18
18
  constructor();
19
- register(type: string, nameOrConfig: any, config?: any): void;
20
- get<T = any>(type: string, name: string): T;
21
- list<T = any>(type: string): T[];
19
+ register(type: string, nameOrConfig: string | Record<string, unknown>, config?: Record<string, unknown>): void;
20
+ get<T = unknown>(type: string, name: string): T;
21
+ list<T = unknown>(type: string): T[];
22
22
  getTypes(): string[];
23
- getEntry<T = any>(type: string, name: string): T;
23
+ getEntry<T = unknown>(type: string, name: string): T;
24
24
  unregister(type: string, name: string): void;
25
25
  /**
26
26
  * Optimized package unregistration with O(k) complexity
@@ -31,7 +31,7 @@ export declare class MetadataRegistry {
31
31
  */
32
32
  unregisterPackage(packageName: string): void;
33
33
  }
34
- export type MetadataItem = any;
34
+ export type MetadataItem = Record<string, unknown>;
35
35
  /**
36
36
  * Legacy Metadata interface - kept for backward compatibility
37
37
  * @deprecated Use MetadataItem from @objectstack/runtime instead
package/dist/registry.js CHANGED
@@ -33,12 +33,12 @@ class MetadataRegistry {
33
33
  }
34
34
  else {
35
35
  item = nameOrConfig;
36
- name = item.name || item.id;
36
+ name = (item.name || item.id);
37
37
  }
38
38
  if (name) {
39
39
  this.items[type][name] = item;
40
40
  // Update package index
41
- const packageName = item.package || item._package || item.packageName;
41
+ const packageName = (item.package || item._package || item.packageName);
42
42
  if (packageName) {
43
43
  if (!this.packageIndex.has(packageName)) {
44
44
  this.packageIndex.set(packageName, new Set());
@@ -77,7 +77,7 @@ class MetadataRegistry {
77
77
  const item = (_a = this.items[type]) === null || _a === void 0 ? void 0 : _a[name];
78
78
  if (item) {
79
79
  // Update package index
80
- const packageName = item.package || item._package || item.packageName;
80
+ const packageName = (item.package || item._package || item.packageName);
81
81
  if (packageName) {
82
82
  const refs = this.packageIndex.get(packageName);
83
83
  if (refs) {
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
@@ -5,19 +5,28 @@
5
5
  * This source code is licensed under the MIT license found in the
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
- import { UnifiedQuery } from "./query";
9
- export interface IObjectRepository {
10
- find(query?: UnifiedQuery): Promise<any[]>;
11
- findOne(idOrQuery: string | number | UnifiedQuery): Promise<any>;
12
- count(filters: any): Promise<number>;
13
- create(doc: any): Promise<any>;
14
- update(id: string | number, doc: any, options?: any): Promise<any>;
15
- delete(id: string | number): Promise<any>;
16
- aggregate(query: any): Promise<any>;
17
- distinct(field: string, filters?: any): Promise<any[]>;
18
- findOneAndUpdate?(filters: any, update: any, options?: any): Promise<any>;
19
- createMany(data: any[]): Promise<any>;
20
- updateMany(filters: any, data: any): Promise<any>;
21
- deleteMany(filters: any): Promise<any>;
22
- execute(actionName: string, id: string | number | undefined, params: any): Promise<any>;
8
+ import { UnifiedQuery, Filter } from "./query";
9
+ /**
10
+ * Repository interface for CRUD operations on a single object type.
11
+ *
12
+ * Note: `object` is used for filter/query parameters instead of `Record<string, unknown>`
13
+ * because named TypeScript interfaces (e.g., UnifiedQuery, Filter) lack implicit index
14
+ * signatures and are not assignable to `Record<string, unknown>`.
15
+ *
16
+ * @typeParam T - The document shape returned by queries. Defaults to `Record<string, unknown>`.
17
+ */
18
+ export interface IObjectRepository<T = Record<string, unknown>> {
19
+ find(query?: UnifiedQuery): Promise<T[]>;
20
+ findOne(idOrQuery: string | number | UnifiedQuery): Promise<T | null>;
21
+ count(filters: Filter | object): Promise<number>;
22
+ create(doc: Record<string, unknown>): Promise<T>;
23
+ update(id: string | number, doc: Record<string, unknown>, options?: Record<string, unknown>): Promise<T>;
24
+ delete(id: string | number): Promise<T>;
25
+ aggregate(query: object): Promise<unknown[]>;
26
+ distinct(field: string, filters?: Filter | object): Promise<unknown[]>;
27
+ findOneAndUpdate?(filters: Filter | object, update: Record<string, unknown>, options?: Record<string, unknown>): Promise<T | null>;
28
+ createMany(data: Record<string, unknown>[]): Promise<T[]>;
29
+ updateMany(filters: Filter | object, data: Record<string, unknown>): Promise<unknown>;
30
+ deleteMany(filters: Filter | object): Promise<unknown>;
31
+ execute(actionName: string, id: string | number | undefined, params: Record<string, unknown>): Promise<unknown>;
23
32
  }
package/dist/sync.d.ts ADDED
@@ -0,0 +1,184 @@
1
+ /**
2
+ * ObjectQL
3
+ * Copyright (c) 2026-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+ /**
9
+ * Sync conflict resolution strategy.
10
+ *
11
+ * - `last-write-wins`: Server accepts the most recent mutation based on timestamp.
12
+ * - `crdt`: Conflict-free Replicated Data Type — field-level merge without conflicts.
13
+ * - `manual`: Conflicts are flagged for manual resolution via a callback.
14
+ */
15
+ export type SyncStrategy = 'last-write-wins' | 'crdt' | 'manual';
16
+ /**
17
+ * Per-object sync configuration.
18
+ *
19
+ * Declared in `*.object.yml` under the `sync` key. Opt-in per object.
20
+ *
21
+ * @example
22
+ * ```yaml
23
+ * name: story
24
+ * sync:
25
+ * enabled: true
26
+ * strategy: last-write-wins
27
+ * conflict_fields: [status]
28
+ * ```
29
+ */
30
+ export interface SyncConfig {
31
+ /** Enable offline sync for this object. Default: false */
32
+ readonly enabled: boolean;
33
+ /** Conflict resolution strategy. Default: 'last-write-wins' */
34
+ readonly strategy?: SyncStrategy;
35
+ /**
36
+ * Fields requiring manual merge when strategy is 'last-write-wins'.
37
+ * Changes to these fields during concurrent edits trigger a conflict.
38
+ */
39
+ readonly conflict_fields?: readonly string[];
40
+ /**
41
+ * Sync direction.
42
+ * - `bidirectional`: Client ↔ Server (default)
43
+ * - `push-only`: Client → Server
44
+ * - `pull-only`: Server → Client
45
+ */
46
+ readonly direction?: 'bidirectional' | 'push-only' | 'pull-only';
47
+ /**
48
+ * Debounce interval in milliseconds before syncing mutations.
49
+ * Batches rapid mutations into a single sync request.
50
+ * Default: 1000
51
+ */
52
+ readonly debounce_ms?: number;
53
+ /**
54
+ * Maximum number of mutations to batch in a single sync request.
55
+ * Default: 50
56
+ */
57
+ readonly batch_size?: number;
58
+ }
59
+ /**
60
+ * Mutation operation type recorded in the client-side mutation log.
61
+ */
62
+ export type MutationOperation = 'create' | 'update' | 'delete';
63
+ /**
64
+ * A single entry in the client-side append-only mutation log.
65
+ *
66
+ * Recorded by WASM drivers when offline. Replayed to the server
67
+ * during sync to achieve eventual consistency.
68
+ */
69
+ export interface MutationLogEntry {
70
+ /** Unique mutation identifier (UUID v7 for time-ordered sorting) */
71
+ readonly id: string;
72
+ /** Object name this mutation applies to */
73
+ readonly objectName: string;
74
+ /** Record identifier */
75
+ readonly recordId: string | number;
76
+ /** Type of mutation */
77
+ readonly operation: MutationOperation;
78
+ /**
79
+ * The mutation payload.
80
+ * - `create`: Full record data.
81
+ * - `update`: Partial field updates (only changed fields).
82
+ * - `delete`: undefined.
83
+ */
84
+ readonly data?: Record<string, unknown>;
85
+ /** ISO 8601 timestamp when the mutation was recorded on the client */
86
+ readonly timestamp: string;
87
+ /** Client device identifier for multi-device conflict resolution */
88
+ readonly clientId: string;
89
+ /** Monotonically increasing sequence number per client */
90
+ readonly sequence: number;
91
+ /**
92
+ * Server-assigned version of the record at the time of mutation.
93
+ * Used for optimistic concurrency during sync.
94
+ * `null` for new records created offline.
95
+ */
96
+ readonly baseVersion: number | null;
97
+ }
98
+ /**
99
+ * Conflict descriptor returned when the server detects a merge conflict.
100
+ */
101
+ export interface SyncConflict {
102
+ /** Object name */
103
+ readonly objectName: string;
104
+ /** Record identifier */
105
+ readonly recordId: string | number;
106
+ /** The client's mutation that caused the conflict */
107
+ readonly clientMutation: MutationLogEntry;
108
+ /** Current server-side record state */
109
+ readonly serverRecord: Record<string, unknown>;
110
+ /** Fields that are in conflict */
111
+ readonly conflictingFields: readonly string[];
112
+ /** Suggested resolution (server-computed) */
113
+ readonly suggestedResolution?: Record<string, unknown>;
114
+ }
115
+ /**
116
+ * Outcome of a single mutation during sync.
117
+ */
118
+ export type SyncMutationResult = {
119
+ readonly status: 'applied';
120
+ readonly serverVersion: number;
121
+ } | {
122
+ readonly status: 'conflict';
123
+ readonly conflict: SyncConflict;
124
+ } | {
125
+ readonly status: 'rejected';
126
+ readonly reason: string;
127
+ };
128
+ /**
129
+ * Client → Server sync request payload.
130
+ */
131
+ export interface SyncPushRequest {
132
+ /** Client device identifier */
133
+ readonly clientId: string;
134
+ /** Mutations to push, ordered by sequence number */
135
+ readonly mutations: readonly MutationLogEntry[];
136
+ /**
137
+ * Last server checkpoint the client has seen.
138
+ * The server uses this to determine what changes to send back.
139
+ */
140
+ readonly lastCheckpoint: string | null;
141
+ }
142
+ /**
143
+ * Server → Client sync response payload.
144
+ */
145
+ export interface SyncPushResponse {
146
+ /** Results for each pushed mutation (same order as request) */
147
+ readonly results: readonly SyncMutationResult[];
148
+ /** Server changes since the client's lastCheckpoint */
149
+ readonly serverChanges: readonly SyncServerChange[];
150
+ /** New checkpoint for the client to store */
151
+ readonly checkpoint: string;
152
+ }
153
+ /**
154
+ * A server-side change to be applied on the client.
155
+ */
156
+ export interface SyncServerChange {
157
+ /** Object name */
158
+ readonly objectName: string;
159
+ /** Record identifier */
160
+ readonly recordId: string | number;
161
+ /** Operation that occurred on the server */
162
+ readonly operation: MutationOperation;
163
+ /** Record data (full for create, partial for update, undefined for delete) */
164
+ readonly data?: Record<string, unknown>;
165
+ /** Server version after this change */
166
+ readonly serverVersion: number;
167
+ /** ISO 8601 timestamp of the server change */
168
+ readonly timestamp: string;
169
+ }
170
+ /**
171
+ * Sync endpoint configuration for the server-side sync service.
172
+ */
173
+ export interface SyncEndpointConfig {
174
+ /** Enable the sync endpoint. Default: false */
175
+ readonly enabled: boolean;
176
+ /** URL path for the sync endpoint. Default: '/api/sync' */
177
+ readonly path?: string;
178
+ /** Maximum mutations per push request. Default: 100 */
179
+ readonly maxMutationsPerRequest?: number;
180
+ /** Maximum age (in days) for server-side change log retention. Default: 30 */
181
+ readonly changeLogRetentionDays?: number;
182
+ /** Enable WebSocket for real-time push from server. Default: false */
183
+ readonly realtime?: boolean;
184
+ }
package/dist/sync.js ADDED
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ /**
3
+ * ObjectQL
4
+ * Copyright (c) 2026-present ObjectStack Inc.
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE file in the root directory of this source tree.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ //# sourceMappingURL=sync.js.map