@rotorsoft/act-sqlite 1.20.2 → 1.20.4
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/.tsbuildinfo +1 -1
- package/dist/@types/sqlite-store.d.ts +12 -0
- package/dist/@types/sqlite-store.d.ts.map +1 -1
- package/dist/index.cjs +55 -113
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +55 -113
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
|
@@ -168,6 +168,18 @@ export declare class SqliteStore implements Store {
|
|
|
168
168
|
ack(leases: Lease[]): Promise<Lease[]>;
|
|
169
169
|
block(leases: BlockedLease[]): Promise<BlockedLease[]>;
|
|
170
170
|
defer(input: string[] | StreamFilter, deferred_at: number): Promise<number>;
|
|
171
|
+
/**
|
|
172
|
+
* Runs `UPDATE streams <set>` on the streams named by `input`, in one
|
|
173
|
+
* write transaction that rolls back on failure. An explicit list is
|
|
174
|
+
* de-duplicated, so a repeated name counts once (matching PG's set-based
|
|
175
|
+
* `stream = ANY(...)`), and updated one name per statement, so a long list
|
|
176
|
+
* never meets SQLite's bound-parameter limit. `set` and `where` bind
|
|
177
|
+
* `params` in order; libSQL `?` placeholders are positional and can't be
|
|
178
|
+
* reused, so a value used twice is passed twice.
|
|
179
|
+
*
|
|
180
|
+
* @returns Count of rows updated.
|
|
181
|
+
*/
|
|
182
|
+
private _update;
|
|
171
183
|
/**
|
|
172
184
|
* Translate a {@link StreamFilter} to a SQLite `WHERE` clause fragment
|
|
173
185
|
* plus positional args. Returns `"1"` (always true) when empty so
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite-store.d.ts","sourceRoot":"","sources":["../../src/sqlite-store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,YAAY,EACZ,SAAS,EACT,SAAS,EACT,KAAK,EACL,OAAO,EACP,KAAK,EACL,iBAAiB,EACjB,YAAY,EACZ,kBAAkB,EAClB,OAAO,EACP,KAAK,EACL,YAAY,EACZ,cAAc,EACd,WAAW,EACX,cAAc,EACd,eAAe,EAChB,MAAM,gBAAgB,CAAC;AAOxB,OAAO,EAEL,KAAK,UAAU,EAGhB,MAAM,uBAAuB,CAAC;AAE/B;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ,0DAA0D;IAC1D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,cAAc,CAAC,EAAE,UAAU,CAAC;CAC7B;AA2FD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAmCzD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qBAAa,WAAY,YAAW,KAAK;IACvC,OAAO,CAAC,MAAM,CAAS;IACvB;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAsC;IAEvE,YAAY,MAAM,EAAE,YAAY,EAQ/B;IAED;;;;;;;OAOG;YACW,wBAAwB;IAUtC;;;;;;;;OAQG;YACW,oBAAoB;IAiB5B,IAAI,
|
|
1
|
+
{"version":3,"file":"sqlite-store.d.ts","sourceRoot":"","sources":["../../src/sqlite-store.ts"],"names":[],"mappings":"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"}
|
package/dist/index.cjs
CHANGED
|
@@ -672,30 +672,45 @@ var SqliteStore = class {
|
|
|
672
672
|
// Cleared by ack/block/reset/unblock. See {@link Store.defer}.
|
|
673
673
|
async defer(input, deferred_at) {
|
|
674
674
|
const at_iso = new Date(deferred_at).toISOString();
|
|
675
|
+
try {
|
|
676
|
+
return await this._update(input, "SET deferred_at = ?, retry = -1", [
|
|
677
|
+
at_iso
|
|
678
|
+
]);
|
|
679
|
+
} catch (e) {
|
|
680
|
+
throw new import_act.StoreError("defer", { cause: e });
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
/**
|
|
684
|
+
* Runs `UPDATE streams <set>` on the streams named by `input`, in one
|
|
685
|
+
* write transaction that rolls back on failure. An explicit list is
|
|
686
|
+
* de-duplicated, so a repeated name counts once (matching PG's set-based
|
|
687
|
+
* `stream = ANY(...)`), and updated one name per statement, so a long list
|
|
688
|
+
* never meets SQLite's bound-parameter limit. `set` and `where` bind
|
|
689
|
+
* `params` in order; libSQL `?` placeholders are positional and can't be
|
|
690
|
+
* reused, so a value used twice is passed twice.
|
|
691
|
+
*
|
|
692
|
+
* @returns Count of rows updated.
|
|
693
|
+
*/
|
|
694
|
+
async _update(input, set, params = [], where) {
|
|
695
|
+
const selections = Array.isArray(input) ? [...new Set(input)].map((stream) => ({
|
|
696
|
+
clause: "stream = ?",
|
|
697
|
+
args: [stream]
|
|
698
|
+
})) : [this._filter_clause(input)];
|
|
675
699
|
const tx = await this.client.transaction("write");
|
|
676
700
|
try {
|
|
677
701
|
let count = 0;
|
|
678
|
-
|
|
679
|
-
for (const stream of new Set(input)) {
|
|
680
|
-
const r = await tx.execute({
|
|
681
|
-
sql: `UPDATE streams SET deferred_at = ?, retry = -1 WHERE stream = ?`,
|
|
682
|
-
args: [at_iso, stream]
|
|
683
|
-
});
|
|
684
|
-
count += r.rowsAffected;
|
|
685
|
-
}
|
|
686
|
-
} else {
|
|
687
|
-
const { clause, args } = this._filter_clause(input);
|
|
702
|
+
for (const { clause, args } of selections) {
|
|
688
703
|
const r = await tx.execute({
|
|
689
|
-
sql: `UPDATE streams
|
|
690
|
-
args: [
|
|
704
|
+
sql: `UPDATE streams ${set} WHERE ${where ? `${where} AND ` : ""}${clause}`,
|
|
705
|
+
args: [...params, ...args]
|
|
691
706
|
});
|
|
692
|
-
count
|
|
707
|
+
count += r.rowsAffected;
|
|
693
708
|
}
|
|
694
709
|
await tx.commit();
|
|
695
710
|
return count;
|
|
696
711
|
} catch (e) {
|
|
697
712
|
await tx.rollback();
|
|
698
|
-
throw
|
|
713
|
+
throw e;
|
|
699
714
|
}
|
|
700
715
|
}
|
|
701
716
|
/**
|
|
@@ -736,103 +751,32 @@ var SqliteStore = class {
|
|
|
736
751
|
return { clause: conditions.length ? conditions.join(" AND ") : "1", args };
|
|
737
752
|
}
|
|
738
753
|
// --- reset: transactional, accepts names or filter ---
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
if (Array.isArray(input)) {
|
|
746
|
-
for (const stream of new Set(input)) {
|
|
747
|
-
const r = await tx.execute({
|
|
748
|
-
sql: `UPDATE streams ${set_clause} WHERE stream = ?`,
|
|
749
|
-
args: [stream]
|
|
750
|
-
});
|
|
751
|
-
count += r.rowsAffected;
|
|
752
|
-
}
|
|
753
|
-
} else {
|
|
754
|
-
const { clause, args } = this._filter_clause(input);
|
|
755
|
-
const r = await tx.execute({
|
|
756
|
-
sql: `UPDATE streams ${set_clause} WHERE ${clause}`,
|
|
757
|
-
args
|
|
758
|
-
});
|
|
759
|
-
count = r.rowsAffected;
|
|
760
|
-
}
|
|
761
|
-
await tx.commit();
|
|
762
|
-
return count;
|
|
763
|
-
} catch (e) {
|
|
764
|
-
await tx.rollback();
|
|
765
|
-
throw e;
|
|
766
|
-
}
|
|
754
|
+
reset(input) {
|
|
755
|
+
return this._update(
|
|
756
|
+
input,
|
|
757
|
+
`SET at = -1, retry = -1, blocked = 0, error = '',
|
|
758
|
+
leased_by = NULL, leased_until = NULL, deferred_at = NULL`
|
|
759
|
+
);
|
|
767
760
|
}
|
|
768
761
|
// --- unblock: clear blocked + retry + lease without touching watermark ---
|
|
769
762
|
// `retry = -1` so claim's post-bump returns retry=0 (first attempt),
|
|
770
|
-
// matching the InMemoryStore convention.
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
WHERE stream = ? AND blocked = 1`,
|
|
782
|
-
args: [stream]
|
|
783
|
-
});
|
|
784
|
-
count += r.rowsAffected;
|
|
785
|
-
}
|
|
786
|
-
} else {
|
|
787
|
-
const { clause, args } = this._filter_clause({
|
|
788
|
-
...input,
|
|
789
|
-
blocked: true
|
|
790
|
-
});
|
|
791
|
-
const r = await tx.execute({
|
|
792
|
-
sql: `UPDATE streams ${set_clause} WHERE ${clause}`,
|
|
793
|
-
args
|
|
794
|
-
});
|
|
795
|
-
count = r.rowsAffected;
|
|
796
|
-
}
|
|
797
|
-
await tx.commit();
|
|
798
|
-
return count;
|
|
799
|
-
} catch (e) {
|
|
800
|
-
await tx.rollback();
|
|
801
|
-
throw e;
|
|
802
|
-
}
|
|
763
|
+
// matching the InMemoryStore convention. Always restricted to blocked
|
|
764
|
+
// rows, whatever the filter says: there is no use case for "unblock
|
|
765
|
+
// unblocked streams."
|
|
766
|
+
unblock(input) {
|
|
767
|
+
return this._update(
|
|
768
|
+
Array.isArray(input) ? input : { ...input, blocked: void 0 },
|
|
769
|
+
`SET retry = -1, blocked = 0, error = '',
|
|
770
|
+
leased_by = NULL, leased_until = NULL, deferred_at = NULL`,
|
|
771
|
+
[],
|
|
772
|
+
"blocked = 1"
|
|
773
|
+
);
|
|
803
774
|
}
|
|
804
775
|
// --- query_streams: read-only introspection with filters ---
|
|
805
776
|
async query_streams(callback, query) {
|
|
806
777
|
const limit = query?.limit ?? 100;
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
if (query?.stream !== void 0) {
|
|
810
|
-
if (query.stream_exact) {
|
|
811
|
-
sql += " AND stream = ?";
|
|
812
|
-
args.push(query.stream);
|
|
813
|
-
} else {
|
|
814
|
-
sql += " AND stream GLOB ?";
|
|
815
|
-
args.push(streamPatternToGlob(query.stream));
|
|
816
|
-
}
|
|
817
|
-
}
|
|
818
|
-
if (query?.source !== void 0) {
|
|
819
|
-
sql += " AND source IS NOT NULL";
|
|
820
|
-
if (query.source_exact) {
|
|
821
|
-
sql += " AND source = ?";
|
|
822
|
-
args.push(query.source);
|
|
823
|
-
} else {
|
|
824
|
-
sql += " AND source GLOB ?";
|
|
825
|
-
args.push(streamPatternToGlob(query.source));
|
|
826
|
-
}
|
|
827
|
-
}
|
|
828
|
-
if (query?.blocked !== void 0) {
|
|
829
|
-
sql += " AND blocked = ?";
|
|
830
|
-
args.push(query.blocked ? 1 : 0);
|
|
831
|
-
}
|
|
832
|
-
if (query?.lane !== void 0) {
|
|
833
|
-
sql += " AND lane = ?";
|
|
834
|
-
args.push(query.lane);
|
|
835
|
-
}
|
|
778
|
+
const { clause, args } = this._filter_clause(query ?? {});
|
|
779
|
+
let sql = `SELECT stream, source, at, retry, blocked, error, leased_by, leased_until, priority, lane, deferred_at, correlated_at FROM streams WHERE ${clause}`;
|
|
836
780
|
if (query?.after !== void 0) {
|
|
837
781
|
sql += " AND stream > ?";
|
|
838
782
|
args.push(query.after);
|
|
@@ -1091,15 +1035,13 @@ var SqliteStore = class {
|
|
|
1091
1035
|
return out;
|
|
1092
1036
|
}
|
|
1093
1037
|
// --- prioritize: bulk priority update with filter ---
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
});
|
|
1102
|
-
return result.rowsAffected;
|
|
1038
|
+
prioritize(filter, priority) {
|
|
1039
|
+
return this._update(
|
|
1040
|
+
filter,
|
|
1041
|
+
"SET priority = ?",
|
|
1042
|
+
[priority, priority],
|
|
1043
|
+
"priority <> ?"
|
|
1044
|
+
);
|
|
1103
1045
|
}
|
|
1104
1046
|
// --- truncate: transactional delete + seed ---
|
|
1105
1047
|
// Windowed targets (`before` set) prune the prefix below the closest safe
|