@stratasync/core 0.2.0

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.
Files changed (90) hide show
  1. package/README.md +83 -0
  2. package/dist/index.d.ts +21 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +14 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/model/base-model.d.ts +82 -0
  7. package/dist/model/base-model.d.ts.map +1 -0
  8. package/dist/model/base-model.js +219 -0
  9. package/dist/model/base-model.js.map +1 -0
  10. package/dist/model/cached-promise.d.ts +15 -0
  11. package/dist/model/cached-promise.d.ts.map +1 -0
  12. package/dist/model/cached-promise.js +50 -0
  13. package/dist/model/cached-promise.js.map +1 -0
  14. package/dist/model/collection.d.ts +33 -0
  15. package/dist/model/collection.d.ts.map +1 -0
  16. package/dist/model/collection.js +181 -0
  17. package/dist/model/collection.js.map +1 -0
  18. package/dist/model/hydration.d.ts +13 -0
  19. package/dist/model/hydration.d.ts.map +1 -0
  20. package/dist/model/hydration.js +2 -0
  21. package/dist/model/hydration.js.map +1 -0
  22. package/dist/model/observability.d.ts +23 -0
  23. package/dist/model/observability.d.ts.map +1 -0
  24. package/dist/model/observability.js +162 -0
  25. package/dist/model/observability.js.map +1 -0
  26. package/dist/reactivity/adapter.d.ts +145 -0
  27. package/dist/reactivity/adapter.d.ts.map +1 -0
  28. package/dist/reactivity/adapter.js +95 -0
  29. package/dist/reactivity/adapter.js.map +1 -0
  30. package/dist/schema/decorators.d.ts +8 -0
  31. package/dist/schema/decorators.d.ts.map +1 -0
  32. package/dist/schema/decorators.js +117 -0
  33. package/dist/schema/decorators.js.map +1 -0
  34. package/dist/schema/hash.d.ts +6 -0
  35. package/dist/schema/hash.d.ts.map +1 -0
  36. package/dist/schema/hash.js +76 -0
  37. package/dist/schema/hash.js.map +1 -0
  38. package/dist/schema/normalize.d.ts +5 -0
  39. package/dist/schema/normalize.d.ts.map +1 -0
  40. package/dist/schema/normalize.js +194 -0
  41. package/dist/schema/normalize.js.map +1 -0
  42. package/dist/schema/registry.d.ts +147 -0
  43. package/dist/schema/registry.d.ts.map +1 -0
  44. package/dist/schema/registry.js +304 -0
  45. package/dist/schema/registry.js.map +1 -0
  46. package/dist/schema/types.d.ts +215 -0
  47. package/dist/schema/types.d.ts.map +1 -0
  48. package/dist/schema/types.js +2 -0
  49. package/dist/schema/types.js.map +1 -0
  50. package/dist/store/types.d.ts +14 -0
  51. package/dist/store/types.d.ts.map +1 -0
  52. package/dist/store/types.js +2 -0
  53. package/dist/store/types.js.map +1 -0
  54. package/dist/sync/delta-applier.d.ts +52 -0
  55. package/dist/sync/delta-applier.d.ts.map +1 -0
  56. package/dist/sync/delta-applier.js +110 -0
  57. package/dist/sync/delta-applier.js.map +1 -0
  58. package/dist/sync/rebase.d.ts +57 -0
  59. package/dist/sync/rebase.d.ts.map +1 -0
  60. package/dist/sync/rebase.js +155 -0
  61. package/dist/sync/rebase.js.map +1 -0
  62. package/dist/sync/sync-id.d.ts +17 -0
  63. package/dist/sync/sync-id.d.ts.map +1 -0
  64. package/dist/sync/sync-id.js +26 -0
  65. package/dist/sync/sync-id.js.map +1 -0
  66. package/dist/sync/types.d.ts +152 -0
  67. package/dist/sync/types.d.ts.map +1 -0
  68. package/dist/sync/types.js +2 -0
  69. package/dist/sync/types.js.map +1 -0
  70. package/dist/transaction/archive.d.ts +16 -0
  71. package/dist/transaction/archive.d.ts.map +1 -0
  72. package/dist/transaction/archive.js +23 -0
  73. package/dist/transaction/archive.js.map +1 -0
  74. package/dist/transaction/create.d.ts +31 -0
  75. package/dist/transaction/create.d.ts.map +1 -0
  76. package/dist/transaction/create.js +121 -0
  77. package/dist/transaction/create.js.map +1 -0
  78. package/dist/transaction/types.d.ts +86 -0
  79. package/dist/transaction/types.d.ts.map +1 -0
  80. package/dist/transaction/types.js +2 -0
  81. package/dist/transaction/types.js.map +1 -0
  82. package/dist/utils/assign.d.ts +9 -0
  83. package/dist/utils/assign.d.ts.map +1 -0
  84. package/dist/utils/assign.js +20 -0
  85. package/dist/utils/assign.js.map +1 -0
  86. package/dist/utils/idempotency.d.ts +16 -0
  87. package/dist/utils/idempotency.d.ts.map +1 -0
  88. package/dist/utils/idempotency.js +39 -0
  89. package/dist/utils/idempotency.js.map +1 -0
  90. package/package.json +37 -0
@@ -0,0 +1,121 @@
1
+ import { generateClientTxId } from "../utils/idempotency.js";
2
+ import { captureArchiveState, createArchivePayload, createUnarchivePatch, createUnarchivePayload, readArchivedAt, } from "./archive.js";
3
+ /**
4
+ * Creates a new transaction with a unique client transaction ID
5
+ */
6
+ const createTransaction = (options) => {
7
+ const tx = {
8
+ action: options.action,
9
+ clientId: options.clientId,
10
+ clientTxId: generateClientTxId(),
11
+ createdAt: Date.now(),
12
+ modelId: options.modelId,
13
+ modelName: options.modelName,
14
+ payload: options.payload,
15
+ retryCount: 0,
16
+ state: "queued",
17
+ };
18
+ if (options.original !== undefined) {
19
+ tx.original = options.original;
20
+ }
21
+ return tx;
22
+ };
23
+ /**
24
+ * Creates a transaction batch from an array of transactions
25
+ */
26
+ export const createTransactionBatch = (transactions) => ({
27
+ batchId: generateClientTxId(),
28
+ createdAt: Date.now(),
29
+ transactions,
30
+ });
31
+ /**
32
+ * Creates an INSERT transaction for a new model instance
33
+ */
34
+ export const createInsertTransaction = (clientId, modelName, modelId, data) => createTransaction({
35
+ action: "I",
36
+ clientId,
37
+ modelId,
38
+ modelName,
39
+ payload: data,
40
+ });
41
+ /**
42
+ * Creates an UPDATE transaction for an existing model instance
43
+ */
44
+ export const createUpdateTransaction = (clientId, modelName, modelId, changes, original) => createTransaction({
45
+ action: "U",
46
+ clientId,
47
+ modelId,
48
+ modelName,
49
+ original,
50
+ payload: changes,
51
+ });
52
+ /**
53
+ * Creates a DELETE transaction for removing a model instance
54
+ */
55
+ export const createDeleteTransaction = (clientId, modelName, modelId, original) => createTransaction({
56
+ action: "D",
57
+ clientId,
58
+ modelId,
59
+ modelName,
60
+ original,
61
+ payload: { ...original },
62
+ });
63
+ /**
64
+ * Creates an ARCHIVE transaction for soft-deleting a model instance
65
+ */
66
+ export const createArchiveTransaction = (clientId, modelName, modelId, options = {}) => createTransaction({
67
+ action: "A",
68
+ clientId,
69
+ modelId,
70
+ modelName,
71
+ original: options.original,
72
+ payload: createArchivePayload(options.archivedAt),
73
+ });
74
+ /**
75
+ * Creates an UNARCHIVE transaction for restoring a soft-deleted model instance
76
+ */
77
+ export const createUnarchiveTransaction = (clientId, modelName, modelId, options = {}) => createTransaction({
78
+ action: "V",
79
+ clientId,
80
+ modelId,
81
+ modelName,
82
+ original: options.original,
83
+ payload: createUnarchivePayload(),
84
+ });
85
+ /**
86
+ * Creates an undo transaction for a given transaction.
87
+ */
88
+ export const createUndoTransaction = (tx, clientId = tx.clientId) => {
89
+ switch (tx.action) {
90
+ case "I": {
91
+ return createDeleteTransaction(clientId, tx.modelName, tx.modelId, tx.payload);
92
+ }
93
+ case "D": {
94
+ if (!tx.original) {
95
+ return null;
96
+ }
97
+ return createInsertTransaction(clientId, tx.modelName, tx.modelId, tx.original);
98
+ }
99
+ case "U": {
100
+ if (!tx.original) {
101
+ return null;
102
+ }
103
+ return createUpdateTransaction(clientId, tx.modelName, tx.modelId, tx.original, tx.payload);
104
+ }
105
+ case "A": {
106
+ return createUnarchiveTransaction(clientId, tx.modelName, tx.modelId, {
107
+ original: captureArchiveState(tx.payload),
108
+ });
109
+ }
110
+ case "V": {
111
+ return createArchiveTransaction(clientId, tx.modelName, tx.modelId, {
112
+ archivedAt: readArchivedAt(tx.original),
113
+ original: createUnarchivePatch(),
114
+ });
115
+ }
116
+ default: {
117
+ return null;
118
+ }
119
+ }
120
+ };
121
+ //# sourceMappingURL=create.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/transaction/create.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,86 @@
1
+ import type { TransactionAction } from "../schema/types.js";
2
+ import type { SyncId } from "../sync/sync-id.js";
3
+ /**
4
+ * State of a transaction in the sync pipeline
5
+ */
6
+ export type TransactionState = "queued" | "sent" | "awaitingSync" | "completed" | "failed";
7
+ /**
8
+ * A single transaction representing a local mutation
9
+ */
10
+ export interface Transaction {
11
+ /** Unique ID generated by the client for idempotency */
12
+ clientTxId: string;
13
+ /** Client instance identifier */
14
+ clientId: string;
15
+ /** Name of the model being mutated */
16
+ modelName: string;
17
+ /** ID of the model instance */
18
+ modelId: string;
19
+ /** Type of mutation */
20
+ action: TransactionAction;
21
+ /** New/changed data for the mutation */
22
+ payload: Record<string, unknown>;
23
+ /** Original data before mutation (for rollback) */
24
+ original?: Record<string, unknown>;
25
+ /** Current state in the sync pipeline */
26
+ state: TransactionState;
27
+ /** Timestamp when transaction was created */
28
+ createdAt: number;
29
+ /** Number of retry attempts */
30
+ retryCount: number;
31
+ /** Last error message if failed */
32
+ lastError?: string;
33
+ /** Sync ID required before the transaction is considered complete */
34
+ syncIdNeededForCompletion?: SyncId;
35
+ /** Batch index used for grouping transactions */
36
+ batchIndex?: number;
37
+ }
38
+ /**
39
+ * A batch of transactions to send to the server
40
+ */
41
+ export interface TransactionBatch {
42
+ /** Unique ID for the batch */
43
+ batchId: string;
44
+ /** Transactions in the batch */
45
+ transactions: Transaction[];
46
+ /** Timestamp when batch was created */
47
+ createdAt: number;
48
+ }
49
+ /**
50
+ * Result of a single transaction from the server
51
+ */
52
+ export interface TransactionResult {
53
+ /** Client transaction ID */
54
+ clientTxId: string;
55
+ /** Whether the transaction succeeded */
56
+ success: boolean;
57
+ /** Assigned sync ID if successful */
58
+ syncId?: SyncId;
59
+ /** Error message if failed */
60
+ error?: string;
61
+ /** Error code if failed */
62
+ errorCode?: string;
63
+ }
64
+ /**
65
+ * Result of a batch mutation from the server
66
+ */
67
+ export interface MutateResult {
68
+ /** Whether the overall batch succeeded */
69
+ success: boolean;
70
+ /** Highest sync ID after mutations */
71
+ lastSyncId: SyncId;
72
+ /** Results for each transaction */
73
+ results: TransactionResult[];
74
+ }
75
+ /**
76
+ * Options for creating a transaction
77
+ */
78
+ export interface CreateTransactionOptions {
79
+ clientId: string;
80
+ modelName: string;
81
+ modelId: string;
82
+ action: TransactionAction;
83
+ payload: Record<string, unknown>;
84
+ original?: Record<string, unknown>;
85
+ }
86
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/transaction/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAEjD;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAExB,QAAQ,GAER,MAAM,GAEN,cAAc,GAEd,WAAW,GAEX,QAAQ,CAAC;AAEb;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,wDAAwD;IACxD,UAAU,EAAE,MAAM,CAAC;IACnB,iCAAiC;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,sCAAsC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,+BAA+B;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,uBAAuB;IACvB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,wCAAwC;IACxC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,mDAAmD;IACnD,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,yCAAyC;IACzC,KAAK,EAAE,gBAAgB,CAAC;IACxB,6CAA6C;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,+BAA+B;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,mCAAmC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,iDAAiD;IACjD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,gCAAgC;IAChC,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,uCAAuC;IACvC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,4BAA4B;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,wCAAwC;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,qCAAqC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2BAA2B;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,0CAA0C;IAC1C,OAAO,EAAE,OAAO,CAAC;IACjB,sCAAsC;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,mCAAmC;IACnC,OAAO,EAAE,iBAAiB,EAAE,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/transaction/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Assigns a value to a target property only if the value is not undefined.
3
+ */
4
+ export declare const assignIfDefined: <T, K extends keyof T>(target: T, key: K, value: T[K] | undefined) => void;
5
+ /**
6
+ * Copies multiple optional fields from source to target, skipping undefined values.
7
+ */
8
+ export declare const assignOptionalFields: <T, S>(target: T, source: S, keys: (keyof T & keyof S)[]) => void;
9
+ //# sourceMappingURL=assign.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assign.d.ts","sourceRoot":"","sources":["../../src/utils/assign.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,eAAe,GAAI,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,EAClD,QAAQ,CAAC,EACT,KAAK,CAAC,EACN,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,KACtB,IAIF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,oBAAoB,GAAI,CAAC,EAAE,CAAC,EACvC,QAAQ,CAAC,EACT,QAAQ,CAAC,EACT,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,KAC1B,IAOF,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Assigns a value to a target property only if the value is not undefined.
3
+ */
4
+ export const assignIfDefined = (target, key, value) => {
5
+ if (value !== undefined) {
6
+ target[key] = value;
7
+ }
8
+ };
9
+ /**
10
+ * Copies multiple optional fields from source to target, skipping undefined values.
11
+ */
12
+ export const assignOptionalFields = (target, source, keys) => {
13
+ for (const key of keys) {
14
+ const value = source[key];
15
+ if (value !== undefined) {
16
+ target[key] = value;
17
+ }
18
+ }
19
+ };
20
+ //# sourceMappingURL=assign.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assign.js","sourceRoot":"","sources":["../../src/utils/assign.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,MAAS,EACT,GAAM,EACN,KAAuB,EACjB,EAAE;IACR,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACtB,CAAC;AACH,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAClC,MAAS,EACT,MAAS,EACT,IAA2B,EACrB,EAAE;IACR,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACvB,MAAkC,CAAC,GAAa,CAAC,GAAG,KAAK,CAAC;QAC7D,CAAC;IACH,CAAC;AACH,CAAC,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Generates a UUID v4
3
+ * Uses crypto.randomUUID when available, falls back to manual generation
4
+ */
5
+ export declare const generateUUID: () => string;
6
+ /**
7
+ * Generates a unique client ID for this browser/device instance
8
+ * Persisted in localStorage to maintain consistency across sessions
9
+ */
10
+ export declare const getOrCreateClientId: (storageKey?: string) => string;
11
+ /**
12
+ * Generates a unique transaction ID
13
+ * Uses UUID v4 format for guaranteed uniqueness
14
+ */
15
+ export declare const generateClientTxId: () => string;
16
+ //# sourceMappingURL=idempotency.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"idempotency.d.ts","sourceRoot":"","sources":["../../src/utils/idempotency.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,YAAY,QAAO,MAa/B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAAI,mBAA6B,KAAG,MAmBnE,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,QAAO,MAAwB,CAAC"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Generates a UUID v4
3
+ * Uses crypto.randomUUID when available, falls back to manual generation
4
+ */
5
+ export const generateUUID = () => {
6
+ const cryptoRef = globalThis
7
+ .crypto;
8
+ if (cryptoRef?.randomUUID) {
9
+ return cryptoRef.randomUUID();
10
+ }
11
+ // Fallback implementation
12
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replaceAll(/[xy]/g, (c) => {
13
+ const r = Math.floor(Math.random() * 16);
14
+ const v = c === "x" ? r : (r % 4) + 8;
15
+ return v.toString(16);
16
+ });
17
+ };
18
+ /**
19
+ * Generates a unique client ID for this browser/device instance
20
+ * Persisted in localStorage to maintain consistency across sessions
21
+ */
22
+ export const getOrCreateClientId = (storageKey = "sync_client_id") => {
23
+ const storage = globalThis.localStorage;
24
+ if (!storage) {
25
+ return generateUUID();
26
+ }
27
+ let clientId = storage.getItem(storageKey);
28
+ if (!clientId) {
29
+ clientId = generateUUID();
30
+ storage.setItem(storageKey, clientId);
31
+ }
32
+ return clientId;
33
+ };
34
+ /**
35
+ * Generates a unique transaction ID
36
+ * Uses UUID v4 format for guaranteed uniqueness
37
+ */
38
+ export const generateClientTxId = () => generateUUID();
39
+ //# sourceMappingURL=idempotency.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"idempotency.js","sourceRoot":"","sources":["../../src/utils/idempotency.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,GAAW,EAAE;IACvC,MAAM,SAAS,GAAI,UAAyD;SACzE,MAAM,CAAC;IACV,IAAI,SAAS,EAAE,UAAU,EAAE,CAAC;QAC1B,OAAO,SAAS,CAAC,UAAU,EAAE,CAAC;IAChC,CAAC;IAED,0BAA0B;IAC1B,OAAO,sCAAsC,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE;QACtE,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;QACzC,MAAM,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;QACtC,OAAO,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IACxB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,UAAU,GAAG,gBAAgB,EAAU,EAAE;IAM3E,MAAM,OAAO,GAAI,UAA6C,CAAC,YAAY,CAAC;IAC5E,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,YAAY,EAAE,CAAC;IACxB,CAAC;IAED,IAAI,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAE3C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,QAAQ,GAAG,YAAY,EAAE,CAAC;QAC1B,OAAO,CAAC,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IACxC,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAW,EAAE,CAAC,YAAY,EAAE,CAAC"}
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@stratasync/core",
3
+ "version": "0.2.0",
4
+ "files": [
5
+ "dist"
6
+ ],
7
+ "type": "module",
8
+ "main": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.js"
14
+ }
15
+ },
16
+ "publishConfig": {
17
+ "access": "public"
18
+ },
19
+ "scripts": {
20
+ "build": "tsc",
21
+ "dev": "tsc --watch",
22
+ "lint": "oxlint .",
23
+ "lint:fix": "oxlint --fix .",
24
+ "format": "oxfmt --write .",
25
+ "format:check": "oxfmt --check .",
26
+ "check-types": "tsc --noEmit",
27
+ "test": "node --test --import tsx \"tests/**/*.test.ts\""
28
+ },
29
+ "devDependencies": {
30
+ "lefthook": "^2.1.4",
31
+ "oxfmt": "^0.41.0",
32
+ "oxlint": "^1.56.0",
33
+ "tsx": "^4.21.0",
34
+ "typescript": "^5.9.3",
35
+ "ultracite": "^7.3.2"
36
+ }
37
+ }