@porulle/core 0.50.2 → 0.50.3
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/package.json
CHANGED
|
@@ -139,6 +139,9 @@ export interface ImportProductsReport extends Record<string, unknown> {
|
|
|
139
139
|
|
|
140
140
|
type Writer = Pick<PluginDb, "insert" | "select">;
|
|
141
141
|
|
|
142
|
+
/** The drizzle handle a transaction context carries (typed `unknown` on the context). */
|
|
143
|
+
const writerOf = (txCtx: TxContext): PluginDb => txCtx.tx as PluginDb;
|
|
144
|
+
|
|
142
145
|
type Failure = { code: ImportRowFailureCode; error: string };
|
|
143
146
|
|
|
144
147
|
function failed(ref: string, code: ImportRowFailureCode, error: string): ImportProductRowResult {
|
|
@@ -473,9 +476,18 @@ export class CatalogImportService {
|
|
|
473
476
|
if (errorPolicy === "reject-everything" && memoryFailures.size > 0) return Ok(rejectAll());
|
|
474
477
|
|
|
475
478
|
try {
|
|
479
|
+
const candidates = page.map((item, index) => ({ item, index })).filter(({ index }) => !memoryFailures.has(index));
|
|
480
|
+
// The shared vocabulary is resolved in its OWN short transaction, never in the page's, and
|
|
481
|
+
// never in a caller's (no ctx is passed on purpose). Inside the page transaction a newly
|
|
482
|
+
// inserted tag's unique key stayed uncommitted for the whole page, so every other page naming
|
|
483
|
+
// it — another store's, or this store's next one — waited on that index until this page
|
|
484
|
+
// committed: 36.6 s behind one 89 s page on the sim, 2026-09-24. The cost is that a page
|
|
485
|
+
// rejected afterwards can leave new vocabulary behind; it is organization-wide and reusable.
|
|
486
|
+
const taxonomy = await this.withTransaction(actor, undefined, (txCtx) =>
|
|
487
|
+
resolveTaxonomy(writerOf(txCtx), orgId, candidates.map(({ item }) => item)));
|
|
488
|
+
|
|
476
489
|
const report = await this.withTransaction(actor, ctx, async (txCtx): Promise<ImportProductsReport> => {
|
|
477
|
-
const tx = txCtx
|
|
478
|
-
const candidates = page.map((item, index) => ({ item, index })).filter(({ index }) => !memoryFailures.has(index));
|
|
490
|
+
const tx = writerOf(txCtx);
|
|
479
491
|
|
|
480
492
|
// Page-level reads: the slugs already taken, then the shared vocabulary.
|
|
481
493
|
const slugs = candidates.map(({ item }) => item.slug);
|
|
@@ -495,7 +507,6 @@ export class CatalogImportService {
|
|
|
495
507
|
if (errorPolicy === "reject-everything" && writable.length < candidates.length) {
|
|
496
508
|
throw new RejectEverything();
|
|
497
509
|
}
|
|
498
|
-
const taxonomy = await resolveTaxonomy(tx, orgId, writable.map(({ item }) => item));
|
|
499
510
|
|
|
500
511
|
const written: Array<{ index: number; write: ItemWrite }> = [];
|
|
501
512
|
for (const { item, index } of writable) {
|