dataply 0.0.18-alpha.2 → 0.0.18

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/cjs/index.js CHANGED
@@ -1764,6 +1764,31 @@ var BPTreeTransaction = class _BPTreeTransaction {
1764
1764
  }
1765
1765
  return true;
1766
1766
  }
1767
+ /**
1768
+ * Selects the best driver key from a condition object.
1769
+ * The driver key determines the starting point and traversal direction for queries.
1770
+ *
1771
+ * @param condition The condition to analyze.
1772
+ * @returns The best driver key or null if no valid key found.
1773
+ */
1774
+ getDriverKey(condition) {
1775
+ if ("primaryEqual" in condition) return "primaryEqual";
1776
+ if ("equal" in condition) return "equal";
1777
+ if ("gt" in condition) return "gt";
1778
+ if ("gte" in condition) return "gte";
1779
+ if ("lt" in condition) return "lt";
1780
+ if ("lte" in condition) return "lte";
1781
+ if ("primaryGt" in condition) return "primaryGt";
1782
+ if ("primaryGte" in condition) return "primaryGte";
1783
+ if ("primaryLt" in condition) return "primaryLt";
1784
+ if ("primaryLte" in condition) return "primaryLte";
1785
+ if ("like" in condition) return "like";
1786
+ if ("notEqual" in condition) return "notEqual";
1787
+ if ("primaryNotEqual" in condition) return "primaryNotEqual";
1788
+ if ("or" in condition) return "or";
1789
+ if ("primaryOr" in condition) return "primaryOr";
1790
+ return null;
1791
+ }
1767
1792
  constructor(rootTx, mvccRoot, mvcc, strategy, comparator, option) {
1768
1793
  this.rootTx = rootTx === null ? this : rootTx;
1769
1794
  this.mvccRoot = mvccRoot;
@@ -2204,8 +2229,8 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
2204
2229
  }
2205
2230
  return void 0;
2206
2231
  }
2207
- *keysStream(condition, filterValues, limit) {
2208
- const stream = this.whereStream(condition, limit);
2232
+ *keysStream(condition, filterValues, limit, order = "asc") {
2233
+ const stream = this.whereStream(condition, limit, order);
2209
2234
  const intersection = filterValues && filterValues.size > 0 ? filterValues : null;
2210
2235
  for (const [key] of stream) {
2211
2236
  if (intersection && !intersection.has(key)) {
@@ -2214,30 +2239,20 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
2214
2239
  yield key;
2215
2240
  }
2216
2241
  }
2217
- *whereStream(condition, limit) {
2218
- let driverKey = null;
2219
- if ("primaryEqual" in condition) driverKey = "primaryEqual";
2220
- else if ("equal" in condition) driverKey = "equal";
2221
- else if ("gt" in condition) driverKey = "gt";
2222
- else if ("gte" in condition) driverKey = "gte";
2223
- else if ("lt" in condition) driverKey = "lt";
2224
- else if ("lte" in condition) driverKey = "lte";
2225
- else if ("primaryGt" in condition) driverKey = "primaryGt";
2226
- else if ("primaryGte" in condition) driverKey = "primaryGte";
2227
- else if ("primaryLt" in condition) driverKey = "primaryLt";
2228
- else if ("primaryLte" in condition) driverKey = "primaryLte";
2229
- else if ("like" in condition) driverKey = "like";
2230
- else if ("notEqual" in condition) driverKey = "notEqual";
2231
- else if ("primaryNotEqual" in condition) driverKey = "primaryNotEqual";
2232
- else if ("or" in condition) driverKey = "or";
2233
- else if ("primaryOr" in condition) driverKey = "primaryOr";
2242
+ *whereStream(condition, limit, order = "asc") {
2243
+ const driverKey = this.getDriverKey(condition);
2234
2244
  if (!driverKey) return;
2235
2245
  const value = condition[driverKey];
2236
- const startNode = this.verifierStartNode[driverKey](value);
2237
- const endNode = this.verifierEndNode[driverKey](value);
2238
- const direction = this.verifierDirection[driverKey];
2246
+ let startNode = this.verifierStartNode[driverKey](value);
2247
+ let endNode = this.verifierEndNode[driverKey](value);
2248
+ let direction = this.verifierDirection[driverKey];
2239
2249
  const comparator = this.verifierMap[driverKey];
2240
2250
  const earlyTerminate = this.verifierEarlyTerminate[driverKey];
2251
+ if (order === "desc") {
2252
+ startNode = endNode ?? this.rightestNode();
2253
+ endNode = null;
2254
+ direction *= -1;
2255
+ }
2241
2256
  const generator = this.getPairsGenerator(
2242
2257
  value,
2243
2258
  startNode,
@@ -2268,16 +2283,16 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
2268
2283
  }
2269
2284
  }
2270
2285
  }
2271
- keys(condition, filterValues) {
2286
+ keys(condition, filterValues, order = "asc") {
2272
2287
  const set = /* @__PURE__ */ new Set();
2273
- for (const key of this.keysStream(condition, filterValues)) {
2288
+ for (const key of this.keysStream(condition, filterValues, void 0, order)) {
2274
2289
  set.add(key);
2275
2290
  }
2276
2291
  return set;
2277
2292
  }
2278
- where(condition) {
2293
+ where(condition, order = "asc") {
2279
2294
  const map = /* @__PURE__ */ new Map();
2280
- for (const [key, value] of this.whereStream(condition)) {
2295
+ for (const [key, value] of this.whereStream(condition, void 0, order)) {
2281
2296
  map.set(key, value);
2282
2297
  }
2283
2298
  return map;
@@ -3033,8 +3048,8 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3033
3048
  }
3034
3049
  return void 0;
3035
3050
  }
3036
- async *keysStream(condition, filterValues, limit) {
3037
- const stream = this.whereStream(condition, limit);
3051
+ async *keysStream(condition, filterValues, limit, order = "asc") {
3052
+ const stream = this.whereStream(condition, limit, order);
3038
3053
  const intersection = filterValues && filterValues.size > 0 ? filterValues : null;
3039
3054
  for await (const [key] of stream) {
3040
3055
  if (intersection && !intersection.has(key)) {
@@ -3043,30 +3058,20 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3043
3058
  yield key;
3044
3059
  }
3045
3060
  }
3046
- async *whereStream(condition, limit) {
3047
- let driverKey = null;
3048
- if ("primaryEqual" in condition) driverKey = "primaryEqual";
3049
- else if ("equal" in condition) driverKey = "equal";
3050
- else if ("gt" in condition) driverKey = "gt";
3051
- else if ("gte" in condition) driverKey = "gte";
3052
- else if ("lt" in condition) driverKey = "lt";
3053
- else if ("lte" in condition) driverKey = "lte";
3054
- else if ("primaryGt" in condition) driverKey = "primaryGt";
3055
- else if ("primaryGte" in condition) driverKey = "primaryGte";
3056
- else if ("primaryLt" in condition) driverKey = "primaryLt";
3057
- else if ("primaryLte" in condition) driverKey = "primaryLte";
3058
- else if ("like" in condition) driverKey = "like";
3059
- else if ("notEqual" in condition) driverKey = "notEqual";
3060
- else if ("primaryNotEqual" in condition) driverKey = "primaryNotEqual";
3061
- else if ("or" in condition) driverKey = "or";
3062
- else if ("primaryOr" in condition) driverKey = "primaryOr";
3061
+ async *whereStream(condition, limit, order = "asc") {
3062
+ const driverKey = this.getDriverKey(condition);
3063
3063
  if (!driverKey) return;
3064
3064
  const value = condition[driverKey];
3065
- const startNode = await this.verifierStartNode[driverKey](value);
3066
- const endNode = await this.verifierEndNode[driverKey](value);
3067
- const direction = this.verifierDirection[driverKey];
3065
+ let startNode = await this.verifierStartNode[driverKey](value);
3066
+ let endNode = await this.verifierEndNode[driverKey](value);
3067
+ let direction = this.verifierDirection[driverKey];
3068
3068
  const comparator = this.verifierMap[driverKey];
3069
3069
  const earlyTerminate = this.verifierEarlyTerminate[driverKey];
3070
+ if (order === "desc") {
3071
+ startNode = endNode ?? await this.rightestNode();
3072
+ endNode = null;
3073
+ direction *= -1;
3074
+ }
3070
3075
  const generator = this.getPairsGenerator(
3071
3076
  value,
3072
3077
  startNode,
@@ -3097,16 +3102,16 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3097
3102
  }
3098
3103
  }
3099
3104
  }
3100
- async keys(condition, filterValues) {
3105
+ async keys(condition, filterValues, order = "asc") {
3101
3106
  const set = /* @__PURE__ */ new Set();
3102
- for await (const key of this.keysStream(condition, filterValues)) {
3107
+ for await (const key of this.keysStream(condition, filterValues, void 0, order)) {
3103
3108
  set.add(key);
3104
3109
  }
3105
3110
  return set;
3106
3111
  }
3107
- async where(condition) {
3112
+ async where(condition, order = "asc") {
3108
3113
  const map = /* @__PURE__ */ new Map();
3109
- for await (const [key, value] of this.whereStream(condition)) {
3114
+ for await (const [key, value] of this.whereStream(condition, void 0, order)) {
3110
3115
  map.set(key, value);
3111
3116
  }
3112
3117
  return map;
@@ -8868,6 +8873,9 @@ var TransactionContext = class {
8868
8873
  get() {
8869
8874
  return this.storage.getStore();
8870
8875
  }
8876
+ stream(tx, callback) {
8877
+ return this.storage.run(tx, callback);
8878
+ }
8871
8879
  };
8872
8880
 
8873
8881
  // src/core/DataplyAPI.ts
@@ -9087,6 +9095,38 @@ var DataplyAPI = class {
9087
9095
  }
9088
9096
  return result;
9089
9097
  }
9098
+ /**
9099
+ * Runs a generator callback function within a transaction context.
9100
+ * Similar to runWithDefault but allows yielding values from an AsyncGenerator.
9101
+ * If no transaction is provided, a new transaction is created.
9102
+ * The transaction is committed if the generator completes successfully,
9103
+ * or rolled back if an error occurs.
9104
+ * @param callback The generator callback function to run within the transaction context.
9105
+ * @param tx The transaction to use. If not provided, a new transaction is created.
9106
+ * @returns An AsyncGenerator that yields values from the callback.
9107
+ */
9108
+ async *streamWithDefault(callback, tx) {
9109
+ const isInternalTx = !tx;
9110
+ if (!tx) {
9111
+ tx = this.createTransaction();
9112
+ }
9113
+ let hasError = false;
9114
+ try {
9115
+ const generator = this.txContext.stream(tx, () => callback(tx));
9116
+ for await (const value of generator) {
9117
+ yield value;
9118
+ }
9119
+ } catch (error) {
9120
+ hasError = true;
9121
+ if (isInternalTx) {
9122
+ await tx.rollback();
9123
+ }
9124
+ throw error;
9125
+ }
9126
+ if (!hasError && isInternalTx) {
9127
+ await tx.commit();
9128
+ }
9129
+ }
9090
9130
  /**
9091
9131
  * Retrieves metadata from the dataply.
9092
9132
  * @returns Metadata of the dataply.
@@ -92,6 +92,17 @@ export declare class DataplyAPI {
92
92
  * @returns The result of the callback function.
93
93
  */
94
94
  protected runWithDefault<T>(callback: (tx: Transaction) => Promise<T>, tx?: Transaction): Promise<T>;
95
+ /**
96
+ * Runs a generator callback function within a transaction context.
97
+ * Similar to runWithDefault but allows yielding values from an AsyncGenerator.
98
+ * If no transaction is provided, a new transaction is created.
99
+ * The transaction is committed if the generator completes successfully,
100
+ * or rolled back if an error occurs.
101
+ * @param callback The generator callback function to run within the transaction context.
102
+ * @param tx The transaction to use. If not provided, a new transaction is created.
103
+ * @returns An AsyncGenerator that yields values from the callback.
104
+ */
105
+ protected streamWithDefault<T>(callback: (tx: Transaction) => AsyncGenerator<T>, tx?: Transaction): AsyncGenerator<T>;
95
106
  /**
96
107
  * Retrieves metadata from the dataply.
97
108
  * @returns Metadata of the dataply.
@@ -3,4 +3,5 @@ export declare class TransactionContext {
3
3
  private readonly storage;
4
4
  run<T>(tx: Transaction, callback: () => T): T;
5
5
  get(): Transaction | undefined;
6
+ stream<T>(tx: Transaction, callback: () => AsyncIterable<T>): AsyncIterable<T>;
6
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dataply",
3
- "version": "0.0.18-alpha.2",
3
+ "version": "0.0.18",
4
4
  "description": "A lightweight storage engine for Node.js with support for MVCC, WAL.",
5
5
  "license": "MIT",
6
6
  "author": "izure <admin@izure.org>",