@stonyx/orm 0.3.2-beta.6 → 0.3.2-beta.7

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.
@@ -8,6 +8,7 @@ const defaultOptions = {
8
8
  serialize: true,
9
9
  transform: true
10
10
  };
11
+ let pendingIdCounter = 0;
11
12
  export function createRecord(modelName, rawData = {}, userOptions = {}) {
12
13
  const orm = Orm.instance;
13
14
  const { initialized } = Orm;
@@ -85,7 +86,7 @@ export function createRecord(modelName, rawData = {}, userOptions = {}) {
85
86
  if (shouldPersist) {
86
87
  const response = { data: { id: record.id } };
87
88
  orm.sqlDb.persist('create', modelName, { rawData }, response).catch((err) => {
88
- log.error?.(`[ORM] Failed to persist create for ${modelName}:${String(record.id)}`, err);
89
+ log.error?.(`[ORM] Failed to persist create for ${modelName}:${String(record.id)}: ${err instanceof Error ? err.message : String(err)}`);
89
90
  });
90
91
  }
91
92
  return record;
@@ -107,7 +108,7 @@ export function updateRecord(record, rawData, userOptions = {}) {
107
108
  const shouldPersist = orm?.sqlDb && !options.isDbRecord && !userOptions._relationshipKey && !options._skipAutoPersist;
108
109
  if (shouldPersist && modelName) {
109
110
  orm.sqlDb.persist('update', modelName, { record, oldState }, {}).catch((err) => {
110
- log.error?.(`[ORM] Failed to persist update for ${modelName}:${String(record.id)}`, err);
111
+ log.error?.(`[ORM] Failed to persist update for ${modelName}:${String(record.id)}: ${err instanceof Error ? err.message : String(err)}`);
111
112
  });
112
113
  }
113
114
  }
@@ -120,9 +121,11 @@ export function updateRecord(record, rawData, userOptions = {}) {
120
121
  function assignRecordId(modelName, rawData) {
121
122
  if (rawData.id)
122
123
  return;
123
- // In SQL mode with numeric IDs, defer to database auto-increment
124
+ // In SQL mode with numeric IDs, defer to database auto-increment.
125
+ // Use unique negative integers — they survive the number transform (parseInt preserves negatives)
126
+ // and avoid NaN store-key collisions that string pending IDs caused.
124
127
  if (Orm.instance?.sqlDb && !isStringIdModel(modelName)) {
125
- rawData.id = `__pending_${Date.now()}_${Math.random()}`;
128
+ rawData.id = -(++pendingIdCounter);
126
129
  rawData.__pendingSqlId = true;
127
130
  return;
128
131
  }
@@ -16,6 +16,7 @@ interface PersistContext {
16
16
  record?: OrmRecord;
17
17
  recordId?: unknown;
18
18
  oldState?: Record<string, unknown>;
19
+ rawData?: Record<string, unknown>;
19
20
  }
20
21
  interface PersistResponse {
21
22
  data?: {
@@ -321,8 +321,10 @@ export default class MysqlDB {
321
321
  if (!record)
322
322
  return;
323
323
  const insertData = this._recordToRow(record, schema);
324
- // For auto-increment models, remove the pending ID
325
- const isPendingId = record.__data.__pendingSqlId;
324
+ // For auto-increment models, remove the pending ID.
325
+ // Check context.rawData (not record.__data) because __pendingSqlId is not a model
326
+ // attribute and gets lost during serialization.
327
+ const isPendingId = context.rawData?.__pendingSqlId === true;
326
328
  if (isPendingId) {
327
329
  delete insertData.id;
328
330
  }
@@ -376,8 +376,10 @@ export default class PostgresDB {
376
376
  if (!record)
377
377
  return;
378
378
  const insertData = this._recordToRow(record, schema, context.rawData);
379
- // For auto-increment models, remove the pending ID
380
- const isPendingId = record.__data.__pendingSqlId;
379
+ // For auto-increment models, remove the pending ID.
380
+ // Check context.rawData (not record.__data) because __pendingSqlId is not a model
381
+ // attribute and gets lost during serialization.
382
+ const isPendingId = context.rawData?.__pendingSqlId === true;
381
383
  if (isPendingId) {
382
384
  delete insertData.id;
383
385
  }
package/dist/store.js CHANGED
@@ -115,7 +115,7 @@ export default class Store {
115
115
  // Auto-persist delete to SQL
116
116
  if (id && Orm.instance?.sqlDb) {
117
117
  Orm.instance.sqlDb.persist('delete', key, { recordId: id }, {}).catch((err) => {
118
- console.error(`[ORM] Failed to persist delete for ${key}:${id}`, err);
118
+ console.error(`[ORM] Failed to persist delete for ${key}:${id}: ${err instanceof Error ? err.message : String(err)}`);
119
119
  });
120
120
  }
121
121
  if (id)
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "stonyx-async",
5
5
  "stonyx-module"
6
6
  ],
7
- "version": "0.3.2-beta.6",
7
+ "version": "0.3.2-beta.7",
8
8
  "description": "",
9
9
  "main": "dist/index.js",
10
10
  "type": "module",
@@ -27,6 +27,8 @@ const defaultOptions: CreateRecordOptions = {
27
27
  transform: true
28
28
  };
29
29
 
30
+ let pendingIdCounter = 0;
31
+
30
32
  export function createRecord(modelName: string, rawData: { [key: string]: unknown } = {}, userOptions: CreateRecordOptions = {}): OrmRecord {
31
33
  const orm = Orm.instance;
32
34
  const { initialized } = Orm;
@@ -118,7 +120,7 @@ export function createRecord(modelName: string, rawData: { [key: string]: unknow
118
120
  if (shouldPersist) {
119
121
  const response = { data: { id: record.id } };
120
122
  orm!.sqlDb!.persist('create', modelName, { rawData }, response).catch((err: unknown) => {
121
- log.error?.(`[ORM] Failed to persist create for ${modelName}:${String(record.id)}`, err);
123
+ log.error?.(`[ORM] Failed to persist create for ${modelName}:${String(record.id)}: ${err instanceof Error ? err.message : String(err)}`);
122
124
  });
123
125
  }
124
126
 
@@ -146,7 +148,7 @@ export function updateRecord(record: OrmRecord, rawData: unknown, userOptions: C
146
148
  const shouldPersist = orm?.sqlDb && !options.isDbRecord && !userOptions._relationshipKey && !options._skipAutoPersist;
147
149
  if (shouldPersist && modelName) {
148
150
  orm!.sqlDb!.persist('update', modelName, { record, oldState }, {}).catch((err: unknown) => {
149
- log.error?.(`[ORM] Failed to persist update for ${modelName}:${String(record.id)}`, err);
151
+ log.error?.(`[ORM] Failed to persist update for ${modelName}:${String(record.id)}: ${err instanceof Error ? err.message : String(err)}`);
150
152
  });
151
153
  }
152
154
  }
@@ -160,9 +162,11 @@ export function updateRecord(record: OrmRecord, rawData: unknown, userOptions: C
160
162
  function assignRecordId(modelName: string, rawData: { [key: string]: unknown }): void {
161
163
  if (rawData.id) return;
162
164
 
163
- // In SQL mode with numeric IDs, defer to database auto-increment
165
+ // In SQL mode with numeric IDs, defer to database auto-increment.
166
+ // Use unique negative integers — they survive the number transform (parseInt preserves negatives)
167
+ // and avoid NaN store-key collisions that string pending IDs caused.
164
168
  if (Orm.instance?.sqlDb && !isStringIdModel(modelName)) {
165
- rawData.id = `__pending_${Date.now()}_${Math.random()}`;
169
+ rawData.id = -(++pendingIdCounter);
166
170
  rawData.__pendingSqlId = true;
167
171
  return;
168
172
  }
@@ -21,6 +21,7 @@ interface PersistContext {
21
21
  record?: OrmRecord;
22
22
  recordId?: unknown;
23
23
  oldState?: Record<string, unknown>;
24
+ rawData?: Record<string, unknown>;
24
25
  }
25
26
 
26
27
  interface PersistResponse {
@@ -420,8 +421,10 @@ export default class MysqlDB {
420
421
 
421
422
  const insertData = this._recordToRow(record, schema);
422
423
 
423
- // For auto-increment models, remove the pending ID
424
- const isPendingId = record.__data.__pendingSqlId;
424
+ // For auto-increment models, remove the pending ID.
425
+ // Check context.rawData (not record.__data) because __pendingSqlId is not a model
426
+ // attribute and gets lost during serialization.
427
+ const isPendingId = context.rawData?.__pendingSqlId === true;
425
428
 
426
429
  if (isPendingId) {
427
430
  delete insertData.id;
@@ -494,8 +494,10 @@ export default class PostgresDB {
494
494
 
495
495
  const insertData = this._recordToRow(record, schema, context.rawData);
496
496
 
497
- // For auto-increment models, remove the pending ID
498
- const isPendingId = record.__data.__pendingSqlId;
497
+ // For auto-increment models, remove the pending ID.
498
+ // Check context.rawData (not record.__data) because __pendingSqlId is not a model
499
+ // attribute and gets lost during serialization.
500
+ const isPendingId = context.rawData?.__pendingSqlId === true;
499
501
 
500
502
  if (isPendingId) {
501
503
  delete insertData.id;
package/src/store.ts CHANGED
@@ -179,7 +179,7 @@ export default class Store {
179
179
  // Auto-persist delete to SQL
180
180
  if (id && Orm.instance?.sqlDb) {
181
181
  Orm.instance.sqlDb.persist('delete', key, { recordId: id }, {}).catch((err: unknown) => {
182
- console.error(`[ORM] Failed to persist delete for ${key}:${id}`, err);
182
+ console.error(`[ORM] Failed to persist delete for ${key}:${id}: ${err instanceof Error ? err.message : String(err)}`);
183
183
  });
184
184
  }
185
185