|
| 1 | +--- |
| 2 | +"@objectstack/core": patch |
| 3 | +"@objectstack/objectql": patch |
| 4 | +"@objectstack/rest": patch |
| 5 | +"@objectstack/metadata-protocol": patch |
| 6 | +--- |
| 7 | + |
| 8 | +fix: harden the bulk-write path — retries, idempotency, contracts, and summary visibility (#3147–#3152) |
| 9 | + |
| 10 | +Six reliability fixes to the batched seed/import + `engine.insert(array)` path |
| 11 | +introduced by the #2678 bulk-write rework: |
| 12 | + |
| 13 | +- **#3151** `bulkWrite` validates that `writeBatch` returns one record per input |
| 14 | + row (a short/long/non-array return is degraded per-row, not backfilled as |
| 15 | + phantom success); `engine.insert(array)` likewise rejects a short driver |
| 16 | + `bulkCreate` return instead of padding afterInsert with `undefined`. |
| 17 | +- **#3150** wraps the two remaining un-retried write points (seed |
| 18 | + `writeRecord`/`resolveDeferredUpdates`, import's no-`createManyData` |
| 19 | + fallback) in `withTransientRetry`; `defaultIsTransientError` short-circuits |
| 20 | + definitive logical errors to non-transient. |
| 21 | +- **#3148** import `resolveRef` flushes pending creates on a same-object miss so |
| 22 | + a later row can reference an earlier same-file CREATE, and no longer |
| 23 | + negatively caches a miss. |
| 24 | +- **#3149** threads an `attempt` counter through `bulkWrite`; seed rechecks by |
| 25 | + `externalId` and import by `matchFields` before re-writing, so a |
| 26 | + commit-then-lost-response retry cannot duplicate a batch. |
| 27 | +- **#3147** `recomputeSummaries` retries transient failures and, on exhaustion, |
| 28 | + surfaces `SummaryRecomputeError` (`ERR_SUMMARY_RECOMPUTE`) instead of a |
| 29 | + silent warn; seed/import recover it to a warning without re-writing. |
| 30 | +- **#3152** autonumbers are assigned after validation, so a batch that dies in |
| 31 | + validation consumes no sequence value (no number-range gaps). |
0 commit comments