@exabugs/dynamodb-client 1.27.0 → 1.27.1

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.
@@ -1,163 +1,123 @@
1
1
  /**
2
2
  * GeoHash近隣検索ロジック
3
3
  *
4
- * Records Lambdaで検証済みの9ブロック検索アルゴリズムを移植
4
+ * 周囲 9 マス(中心 + 隣接 8 方向)のシャドーだけを読み、位置の近似から、確定できる範囲で打ち切る。
5
+ * 本体レコードは、最後に、結果になりうる候補だけを 1 回読む。
6
+ *
7
+ * 保証できる半径 r(p, 緯度) = 精度 p のマスの短い辺。検索点から r 以内の点は、必ず周囲 9 マスの中にある
8
+ * (検索点は中央のマスのどこにでもあるので、9 マスの縁までの最短距離は、マス 1 つぶんの短い辺)。
5
9
  */
6
- import { DEFAULT_GEOHASH_CONFIG, calculateDistance, encodeGeoHash, extractCoordinatesFromNearQuery, extractMaxDistanceFromNearQuery, extractMinDistanceFromNearQuery, getNeighborGeoHashes, } from '../../shared/geohash/index.js';
10
+ import { DEFAULT_GEOHASH_CONFIG, calculateDistance, decodeGeoHash, encodeGeoHash, extractCoordinatesFromNearQuery, extractMaxDistanceFromNearQuery, extractMinDistanceFromNearQuery, getNeighborGeoHashes, } from '../../shared/geohash/index.js';
11
+ /** 緯度 1 度の長さ(メートル)。経度 1 度の長さの上限(赤道)にも使う(実際は地球の半径から求めるより少し長い) */
12
+ const METERS_PER_DEGREE = 111320;
7
13
  /**
8
- * GeoHash精度ごとの誤差範囲(メートル)
9
- * 9ブロック検索(3×3)での実効カバー範囲を計算
14
+ * 精度 p のマスの(緯度方向の高さ, 経度方向の幅)。メートル。経度は `cosLat` を掛ける
15
+ *
16
+ * geohash は経度から先に 1 ビットずつ割る。精度 p は 5p ビットで、経度が ceil(5p/2)、緯度が floor(5p/2)
10
17
  */
11
- const GEOHASH_COVERAGE = {
12
- 8: 19 * 3, // ±19m × 3 = 約57m
13
- 7: 76 * 3, // ±76m × 3 = 約228m
14
- 6: 610 * 3, // ±610m × 3 = 約1,830m (1.8km)
15
- 5: 2400 * 3, // ±2.4km × 3 = 約7,200m (7.2km)
16
- 4: 20000 * 3, // ±20km × 3 = 約60,000m (60km)
17
- 3: 78000 * 3, // ±78km × 3 = 約234,000m (234km)
18
- 2: 630000 * 3, // ±630km × 3 = 約1,890,000m (1,890km)
19
- };
18
+ function cellSizeMeters(precision, cosLat) {
19
+ const latBits = Math.floor((5 * precision) / 2);
20
+ const lonBits = Math.ceil((5 * precision) / 2);
21
+ const heightDeg = 180 / 2 ** latBits;
22
+ return {
23
+ height: heightDeg * METERS_PER_DEGREE,
24
+ width: (360 / 2 ** lonBits) * METERS_PER_DEGREE * cosLat,
25
+ heightDeg,
26
+ };
27
+ }
20
28
  /**
21
- * 指定された精度での9ブロック検索がmaxDistanceをカバーしているか判定
29
+ * 精度 p で保証できる半径(メートル)= マスの短い辺
30
+ *
31
+ * 経度方向の幅は、周囲 9 マスのうち最も高緯度の縁の cos を使う(高緯度ほど狭い)。
22
32
  */
23
- function coversMaxDistance(precision, maxDistance) {
24
- const coverage = GEOHASH_COVERAGE[precision];
25
- if (!coverage) {
26
- return false;
27
- }
28
- return coverage >= maxDistance;
33
+ export function guaranteedRadius(precision, latitude) {
34
+ const { heightDeg } = cellSizeMeters(precision, 1);
35
+ const worstLatitude = Math.min(89.9, Math.abs(latitude) + 2 * heightDeg);
36
+ const { height, width } = cellSizeMeters(precision, Math.cos((worstLatitude * Math.PI) / 180));
37
+ return Math.min(height, width);
38
+ }
39
+ /** シャドーの精度の位置の誤差 ε(メートル)= マスの対角線の半分(経度は赤道の長さで見て、上限にする) */
40
+ export function shadowPositionError(shadowPrecision) {
41
+ const { height, width } = cellSizeMeters(shadowPrecision, 1);
42
+ return Math.hypot(height, width) / 2;
43
+ }
44
+ /** 近似の距離の列から、k 番目に小さいもの(k 件に足りなければ undefined)。昇順に並べて渡すこと */
45
+ function kthOf(sortedAscending, k) {
46
+ return sortedAscending.length >= k ? sortedAscending[k - 1] : undefined;
29
47
  }
30
48
  /**
31
- * 9ブロック検索を実行
49
+ * 近隣検索を実行
32
50
  *
33
- * Records Lambdaの`findVenueCandidates`関数のロジックを移植。
34
- * 段階的に精度を緩和しながら、9ブロック(中心 + 隣接8方向)を検索します。
51
+ * 1. 周囲 9 マスのシャドーを読み、近似の距離 d̃ を求める(重複は id で消える)
52
+ * 2. 上位 limit 件が 9 マスの中で確定する(d̃ₖ + ε ≤ r)か、円の全体を 9 マスが覆う(maxDistance + ε ≤ r)
53
+ * まで、精度を 1 つずつ下げて 1 に戻る(`minPrecision` まで)
54
+ * 3. d̃ が d̃ₖ + 2ε 以内の候補(maxDistance・minDistance があればその範囲)だけの本体を、1 回読む
35
55
  *
36
56
  * @param nearQuery - $nearクエリ
37
57
  * @param fieldName - GeoHashフィールド名
38
58
  * @param limit - 取得件数
39
- * @param searchFunction - 実際の検索を実行する関数
59
+ * @param searchShadows - 1 マス(geohash の接頭辞)のシャドーを読む関数
60
+ * @param readBodies - id の本体を読む関数(ほかの条件で絞る場合は、ここで絞る)
40
61
  * @param config - GeoHash設定
41
- * @returns 距離付きドキュメントと検索メタデータ
42
- *
43
- * @example
44
- * ```typescript
45
- * const result = await executeNearSearch(
46
- * { latitude: 35.6812, longitude: 139.7671, maxDistance: 5000 },
47
- * 'location',
48
- * 10,
49
- * async (geohashPrefix) => {
50
- * // DynamoDBから検索
51
- * return await collection.find({ geohash: { $regex: `^${geohashPrefix}` } }).toArray();
52
- * }
53
- * );
54
- * ```
55
62
  */
56
- export async function executeNearSearch(nearQuery, fieldName, limit, searchFunction, config = DEFAULT_GEOHASH_CONFIG) {
57
- // クエリから緯度・経度を抽出
63
+ export async function executeNearSearch(nearQuery, fieldName, limit, searchShadows, readBodies, config = DEFAULT_GEOHASH_CONFIG) {
58
64
  const { latitude, longitude } = extractCoordinatesFromNearQuery(nearQuery);
59
65
  const maxDistance = extractMaxDistanceFromNearQuery(nearQuery);
60
66
  const minDistance = extractMinDistanceFromNearQuery(nearQuery);
67
+ const epsilon = shadowPositionError(config.shadowPrecision);
61
68
  let precision = config.searchPrecision;
62
- let allCandidates = [];
63
69
  let iterations = 0;
64
- // 段階的に精度を緩和しながら検索
65
- while (allCandidates.length < limit * config.candidateMultiplier &&
66
- precision >= config.minPrecision &&
67
- iterations < config.maxIterations) {
70
+ let exhaustive = false;
71
+ /** id → 近似の距離 d̃ */
72
+ let approx = new Map();
73
+ /** 上位 limit 件を確定できた d̃ₖ(確定できなければ undefined) */
74
+ let kth;
75
+ while (precision >= config.minPrecision && iterations < config.maxIterations) {
68
76
  iterations++;
69
- // 現在の精度でGeoHashを再計算
70
- const currentGeoHash = encodeGeoHash(latitude, longitude, precision);
71
- // 隣接する8方向のGeoHashを取得(合計9ブロック)
72
- const neighborGeoHashes = getNeighborGeoHashes(currentGeoHash);
73
- // 9ブロック分のGeoHashで並列検索
74
- const searchPromises = neighborGeoHashes.map((geohash) => searchFunction(geohash));
75
- const results = await Promise.all(searchPromises);
76
- const candidates = results.flat();
77
- // 重複を除外して追加
78
- for (const candidate of candidates) {
79
- if (!allCandidates.some((c) => c.id === candidate.id)) {
80
- allCandidates.push(candidate);
81
- }
77
+ const radius = guaranteedRadius(precision, latitude);
78
+ const neighbors = getNeighborGeoHashes(encodeGeoHash(latitude, longitude, precision));
79
+ const hits = (await Promise.all(neighbors.map((prefix) => searchShadows(prefix)))).flat();
80
+ // 精度を下げた回は、前の回の範囲を含むので、作り直す
81
+ approx = new Map();
82
+ for (const hit of hits) {
83
+ const center = decodeGeoHash(hit.geohash);
84
+ approx.set(hit.id, calculateDistance(latitude, longitude, center.latitude, center.longitude));
82
85
  }
83
- // maxDistanceが指定されている場合、距離内の候補数をチェック
84
- if (maxDistance !== undefined) {
85
- // 現在の候補から距離内のものをカウント
86
- let candidatesWithinDistance = 0;
87
- for (const candidate of allCandidates) {
88
- const location = candidate[fieldName];
89
- if (location &&
90
- typeof location.latitude === 'number' &&
91
- typeof location.longitude === 'number') {
92
- const distance = calculateDistance(latitude, longitude, location.latitude, location.longitude);
93
- if (distance <= maxDistance) {
94
- candidatesWithinDistance++;
95
- }
96
- }
97
- }
98
- // 距離内の候補が十分に見つかったら終了
99
- if (candidatesWithinDistance >= limit) {
100
- console.log('[nearSearch] Early termination: found enough candidates within maxDistance', {
101
- candidatesWithinDistance,
102
- limit,
103
- maxDistance,
104
- precision,
105
- iterations,
106
- });
107
- break;
108
- }
109
- // 現在の精度での検索範囲がmaxDistanceを完全にカバーしている場合、
110
- // これ以上精度を緩和しても意味がないので終了
111
- if (coversMaxDistance(precision, maxDistance)) {
112
- console.log('[nearSearch] Early termination: current precision covers maxDistance', {
113
- precision,
114
- maxDistance,
115
- coverage: GEOHASH_COVERAGE[precision],
116
- candidatesWithinDistance,
117
- iterations,
118
- });
119
- break;
120
- }
86
+ // 結果になることが確かな候補(真の距離が minDistance 以上・maxDistance 以下)の中で、k 番目に近いもの
87
+ const sure = [...approx.values()]
88
+ .filter((d) => (minDistance === undefined || d - epsilon >= minDistance) &&
89
+ (maxDistance === undefined || d + epsilon <= maxDistance))
90
+ .sort((a, b) => a - b);
91
+ kth = kthOf(sure, limit);
92
+ const topKConfirmed = kth !== undefined && kth + epsilon <= radius;
93
+ const circleCovered = maxDistance !== undefined && maxDistance + epsilon <= radius;
94
+ if (topKConfirmed || circleCovered) {
95
+ exhaustive = true;
96
+ break;
121
97
  }
122
- // 精度を1文字減らす(検索範囲を広げる)
123
98
  precision--;
124
99
  }
125
- // 距離計算・フィルタリング・ソート
126
- const documentsWithDistance = allCandidates
100
+ // 本体を読む候補: 近似の距離が d̃ₖ + 2ε 以内(確定した上位 limit 件の真の距離は、d̃ₖ + ε 以内)
101
+ const cutoff = kth !== undefined ? kth + 2 * epsilon : undefined;
102
+ const wanted = [...approx.entries()]
103
+ .filter(([, d]) => (cutoff === undefined || d <= cutoff) &&
104
+ (maxDistance === undefined || d <= maxDistance + epsilon) &&
105
+ (minDistance === undefined || d >= minDistance - epsilon))
106
+ .map(([id]) => id);
107
+ const bodies = wanted.length > 0 ? await readBodies(wanted) : [];
108
+ const documents = bodies
127
109
  .map((doc) => {
128
- // フィールドから地理座標を取得
129
110
  const location = doc[fieldName];
130
- // デバッグログ: locationフィールドの内容を確認
131
- if (!location) {
132
- console.log('[nearSearch] Location field not found:', {
133
- fieldName,
134
- docKeys: Object.keys(doc),
135
- doc: JSON.stringify(doc).substring(0, 200),
136
- });
137
- }
138
111
  if (!location ||
139
112
  typeof location.latitude !== 'number' ||
140
113
  typeof location.longitude !== 'number') {
141
114
  return null;
142
115
  }
143
- // 距離計算
144
116
  const distance = calculateDistance(latitude, longitude, location.latitude, location.longitude);
145
- // デバッグログ: 距離計算結果
146
- console.log('[nearSearch] Distance calculated:', {
147
- docId: doc.id,
148
- distance,
149
- maxDistance,
150
- minDistance,
151
- willBeFiltered: (maxDistance !== undefined && distance > maxDistance) ||
152
- (minDistance !== undefined && distance < minDistance),
153
- });
154
- // 距離フィルタリング
155
- if (maxDistance !== undefined && distance > maxDistance) {
117
+ if (maxDistance !== undefined && distance > maxDistance)
156
118
  return null;
157
- }
158
- if (minDistance !== undefined && distance < minDistance) {
119
+ if (minDistance !== undefined && distance < minDistance)
159
120
  return null;
160
- }
161
121
  return {
162
122
  ...doc,
163
123
  __distance: distance,
@@ -168,11 +128,13 @@ export async function executeNearSearch(nearQuery, fieldName, limit, searchFunct
168
128
  .sort((a, b) => (a.__distance ?? 0) - (b.__distance ?? 0))
169
129
  .slice(0, limit);
170
130
  return {
171
- documents: documentsWithDistance,
131
+ documents,
172
132
  metadata: {
173
133
  iterations,
174
- candidatesFound: allCandidates.length,
134
+ candidatesFound: approx.size,
135
+ bodiesRead: wanted.length,
175
136
  requestedLimit: limit,
137
+ exhaustive,
176
138
  },
177
139
  };
178
140
  }
@@ -1 +1 @@
1
- {"version":3,"file":"nearSearch.js","sourceRoot":"","sources":["../../../src/server/query/nearSearch.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"nearSearch.js","sourceRoot":"","sources":["../../../src/server/query/nearSearch.ts"],"names":[],"mappings":"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"}
@@ -3,14 +3,25 @@ export interface ResolvedUpdate {
3
3
  patch: Record<string, unknown>;
4
4
  /** 新規作成のときだけ入れる値($setOnInsert) */
5
5
  setOnInsert: Record<string, unknown>;
6
+ /** 足す値($inc。項目名(ドット記法可)→ 有限の数値)。今の値の読み取りと加算は updateMany が行う */
7
+ inc: Record<string, number>;
6
8
  /** レスポンスの items に返す値($set の値。演算子が無ければパッチそのもの) */
7
9
  returned: Record<string, unknown>;
8
10
  }
11
+ /** ドット記法のパスで、今の値を読む(途中がオブジェクトでなければ undefined) */
12
+ export declare function readByPath(data: Record<string, unknown>, path: string): unknown;
13
+ /**
14
+ * $inc を当てる(今の値に足した値を $set として書くパッチを作る)
15
+ *
16
+ * 項目が無い・null のときは 0 から足す。数値でないときは 400。
17
+ * 返す `added` は、足した後の値(レスポンスの items 用)。
18
+ */
19
+ export declare function applyInc(data: Record<string, unknown>, inc: Record<string, number>): Record<string, number>;
9
20
  /**
10
21
  * 更新のデータを解釈する
11
22
  *
12
23
  * - 演算子(`$` で始まるキー)が無ければ、全体を JSON Merge Patch として扱う
13
- * - 演算子があれば、$set / $setOnInsert / $unset だけを受け付ける(ほかは 400)
24
+ * - 演算子があれば、$set / $setOnInsert / $unset / $inc だけを受け付ける(ほかは 400)
14
25
  *
15
26
  * @throws AppError VALIDATION_ERROR(400)
16
27
  */
@@ -1 +1 @@
1
- {"version":3,"file":"updateOperators.d.ts","sourceRoot":"","sources":["../../../src/server/utils/updateOperators.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,cAAc;IAC7B,iEAAiE;IACjE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,kCAAkC;IAClC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,iDAAiD;IACjD,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AA0BD;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,cAAc,CAuBpF;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAQzF"}
1
+ {"version":3,"file":"updateOperators.d.ts","sourceRoot":"","sources":["../../../src/server/utils/updateOperators.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,cAAc;IAC7B,iEAAiE;IACjE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,kCAAkC;IAClC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,+DAA+D;IAC/D,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,iDAAiD;IACjD,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAsCD,iDAAiD;AACjD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAO/E;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CACtB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC1B,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAcxB;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,cAAc,CA6BpF;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAQzF"}
@@ -1,11 +1,11 @@
1
1
  /**
2
- * 更新演算子($set / $setOnInsert / $unset)の解釈
2
+ * 更新演算子($set / $setOnInsert / $unset / $inc)の解釈
3
3
  *
4
- * 対応していない演算子($inc など)を黙って無視しない。無視すると、呼び出し側は更新できたと
4
+ * 対応していない演算子($push など)を黙って無視しない。無視すると、呼び出し側は更新できたと
5
5
  * 思い込む($unset が無視され、項目を空にする操作が保存されない不具合が実際に起きた)。
6
6
  */
7
7
  import { AppError, ErrorCode } from '../../shared/index.js';
8
- const SUPPORTED_OPERATORS = ['$set', '$setOnInsert', '$unset'];
8
+ const SUPPORTED_OPERATORS = ['$set', '$setOnInsert', '$unset', '$inc'];
9
9
  function invalid(message) {
10
10
  return new AppError(ErrorCode.VALIDATION_ERROR, message, 400);
11
11
  }
@@ -29,18 +29,58 @@ function unsetFields(value) {
29
29
  }
30
30
  return Object.keys(asObject(value, '$unset'));
31
31
  }
32
+ /** $inc は、項目名 → 有限の数値。それ以外は 400 */
33
+ function incFields(value) {
34
+ const inc = {};
35
+ for (const [field, amount] of Object.entries(asObject(value, '$inc'))) {
36
+ if (typeof amount !== 'number' || !Number.isFinite(amount)) {
37
+ throw invalid(`$inc value for "${field}" must be a finite number`);
38
+ }
39
+ inc[field] = amount;
40
+ }
41
+ return inc;
42
+ }
43
+ /** ドット記法のパスで、今の値を読む(途中がオブジェクトでなければ undefined) */
44
+ export function readByPath(data, path) {
45
+ let current = data;
46
+ for (const key of path.split('.')) {
47
+ if (typeof current !== 'object' || current === null)
48
+ return undefined;
49
+ current = current[key];
50
+ }
51
+ return current;
52
+ }
53
+ /**
54
+ * $inc を当てる(今の値に足した値を $set として書くパッチを作る)
55
+ *
56
+ * 項目が無い・null のときは 0 から足す。数値でないときは 400。
57
+ * 返す `added` は、足した後の値(レスポンスの items 用)。
58
+ */
59
+ export function applyInc(data, inc) {
60
+ const added = {};
61
+ for (const [field, amount] of Object.entries(inc)) {
62
+ const current = readByPath(data, field);
63
+ if (current !== undefined &&
64
+ current !== null &&
65
+ (typeof current !== 'number' || !Number.isFinite(current))) {
66
+ throw invalid(`Field "${field}" is not a number, $inc cannot be applied`);
67
+ }
68
+ added[field] = (current ?? 0) + amount;
69
+ }
70
+ return added;
71
+ }
32
72
  /**
33
73
  * 更新のデータを解釈する
34
74
  *
35
75
  * - 演算子(`$` で始まるキー)が無ければ、全体を JSON Merge Patch として扱う
36
- * - 演算子があれば、$set / $setOnInsert / $unset だけを受け付ける(ほかは 400)
76
+ * - 演算子があれば、$set / $setOnInsert / $unset / $inc だけを受け付ける(ほかは 400)
37
77
  *
38
78
  * @throws AppError VALIDATION_ERROR(400)
39
79
  */
40
80
  export function resolveUpdateOperators(data) {
41
81
  const operators = Object.keys(data).filter((key) => key.startsWith('$'));
42
82
  if (operators.length === 0) {
43
- return { patch: data, setOnInsert: {}, returned: data };
83
+ return { patch: data, setOnInsert: {}, inc: {}, returned: data };
44
84
  }
45
85
  const unsupported = operators.filter((op) => !SUPPORTED_OPERATORS.includes(op));
46
86
  if (unsupported.length > 0) {
@@ -54,7 +94,14 @@ export function resolveUpdateOperators(data) {
54
94
  }
55
95
  patch[field] = null;
56
96
  }
57
- return { patch, setOnInsert: asObject(data.$setOnInsert, '$setOnInsert'), returned: set };
97
+ const inc = incFields(data.$inc);
98
+ for (const field of Object.keys(inc)) {
99
+ if (field in set)
100
+ throw invalid(`Field "${field}" is in both $set and $inc`);
101
+ if (field in patch)
102
+ throw invalid(`Field "${field}" is in both $unset and $inc`);
103
+ }
104
+ return { patch, setOnInsert: asObject(data.$setOnInsert, '$setOnInsert'), inc, returned: set };
58
105
  }
59
106
  /**
60
107
  * フィルタから、新規作成(upsert)のレコードに入れる値を取り出す
@@ -1 +1 @@
1
- {"version":3,"file":"updateOperators.js","sourceRoot":"","sources":["../../../src/server/utils/updateOperators.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"updateOperators.js","sourceRoot":"","sources":["../../../src/server/utils/updateOperators.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exabugs/dynamodb-client",
3
- "version": "1.27.0",
3
+ "version": "1.27.1",
4
4
  "description": "DynamoDB Single-Table Client SDK with MongoDB-like API, Shadow Records, and Lambda implementation for serverless applications",
5
5
  "author": "exabugs",
6
6
  "license": "MIT",