opticedge-cloud-utils 1.1.12 → 1.1.14

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.
@@ -0,0 +1 @@
1
+ export declare function chunkByBytes(arr: any[], maxBytes?: number): any[][];
package/dist/chunk.js ADDED
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ /* eslint-disable @typescript-eslint/no-explicit-any */
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.chunkByBytes = chunkByBytes;
5
+ function chunkByBytes(arr, maxBytes = 700000) {
6
+ // 700KB safe default
7
+ const chunks = [];
8
+ let current = [];
9
+ let curBytes = 0;
10
+ for (const item of arr) {
11
+ const s = JSON.stringify(item);
12
+ const b = Buffer.byteLength(s, 'utf8');
13
+ // if a single item exceeds maxBytes, push it alone (or skip)
14
+ if (b > maxBytes) {
15
+ // optionally log and skip - here we'll push as its own chunk
16
+ if (current.length) {
17
+ chunks.push(current);
18
+ current = [];
19
+ curBytes = 0;
20
+ }
21
+ chunks.push([item]);
22
+ continue;
23
+ }
24
+ if (curBytes + b > maxBytes) {
25
+ chunks.push(current);
26
+ current = [item];
27
+ curBytes = b;
28
+ }
29
+ else {
30
+ current.push(item);
31
+ curBytes += b;
32
+ }
33
+ }
34
+ if (current.length)
35
+ chunks.push(current);
36
+ return chunks;
37
+ }
@@ -1,4 +1,5 @@
1
- import { Collection, Document } from 'mongodb';
1
+ import { Db, Collection, Document } from 'mongodb';
2
2
  export declare function connectToMongo(projectId: string, uriSecret: string, dbName: string): Promise<void>;
3
3
  export declare function connectToMongoWithUri(uri: string, dbName: string): Promise<void>;
4
+ export declare function getDb(): Db;
4
5
  export declare function getCollection<T extends Document = Document>(name: string): Collection<T>;
package/dist/db/mongo.js CHANGED
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.connectToMongo = connectToMongo;
4
4
  exports.connectToMongoWithUri = connectToMongoWithUri;
5
+ exports.getDb = getDb;
5
6
  exports.getCollection = getCollection;
6
7
  const mongodb_1 = require("mongodb");
7
8
  const secrets_1 = require("../secrets");
@@ -33,6 +34,11 @@ async function connectToMongoWithUri(uri, dbName) {
33
34
  }
34
35
  await connectPromise;
35
36
  }
37
+ function getDb() {
38
+ if (!db)
39
+ throw new Error('Mongo not initialized. Call connectToMongo(...) first.');
40
+ return db;
41
+ }
36
42
  function getCollection(name) {
37
43
  if (!db)
38
44
  throw new Error('Mongo not initialized');
package/dist/env.js CHANGED
@@ -1,4 +1,5 @@
1
1
  "use strict";
2
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
3
  Object.defineProperty(exports, "__esModule", { value: true });
3
4
  exports.getEnv = getEnv;
4
5
  function getEnv(name, fallback) {
package/dist/index.d.ts CHANGED
@@ -4,6 +4,7 @@ export * from './db/mongo3';
4
4
  export * from './tw/utils';
5
5
  export * from './tw/wallet';
6
6
  export * from './auth';
7
+ export * from './chunk';
7
8
  export * from './env';
8
9
  export * from './parser';
9
10
  export * from './regex';
package/dist/index.js CHANGED
@@ -20,6 +20,7 @@ __exportStar(require("./db/mongo3"), exports);
20
20
  __exportStar(require("./tw/utils"), exports);
21
21
  __exportStar(require("./tw/wallet"), exports);
22
22
  __exportStar(require("./auth"), exports);
23
+ __exportStar(require("./chunk"), exports);
23
24
  __exportStar(require("./env"), exports);
24
25
  __exportStar(require("./parser"), exports);
25
26
  __exportStar(require("./regex"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opticedge-cloud-utils",
3
- "version": "1.1.12",
3
+ "version": "1.1.14",
4
4
  "description": "Common utilities for cloud functions",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/chunk.ts ADDED
@@ -0,0 +1,33 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+
3
+ export function chunkByBytes(arr: any[], maxBytes = 700_000) {
4
+ // 700KB safe default
5
+ const chunks: any[][] = []
6
+ let current: any[] = []
7
+ let curBytes = 0
8
+ for (const item of arr) {
9
+ const s = JSON.stringify(item)
10
+ const b = Buffer.byteLength(s, 'utf8')
11
+ // if a single item exceeds maxBytes, push it alone (or skip)
12
+ if (b > maxBytes) {
13
+ // optionally log and skip - here we'll push as its own chunk
14
+ if (current.length) {
15
+ chunks.push(current)
16
+ current = []
17
+ curBytes = 0
18
+ }
19
+ chunks.push([item])
20
+ continue
21
+ }
22
+ if (curBytes + b > maxBytes) {
23
+ chunks.push(current)
24
+ current = [item]
25
+ curBytes = b
26
+ } else {
27
+ current.push(item)
28
+ curBytes += b
29
+ }
30
+ }
31
+ if (current.length) chunks.push(current)
32
+ return chunks
33
+ }
package/src/db/mongo.ts CHANGED
@@ -34,6 +34,11 @@ export async function connectToMongoWithUri(uri: string, dbName: string) {
34
34
  await connectPromise
35
35
  }
36
36
 
37
+ export function getDb(): Db {
38
+ if (!db) throw new Error('Mongo not initialized. Call connectToMongo(...) first.')
39
+ return db
40
+ }
41
+
37
42
  export function getCollection<T extends Document = Document>(name: string): Collection<T> {
38
43
  if (!db) throw new Error('Mongo not initialized')
39
44
  return db.collection<T>(name)
package/src/env.ts CHANGED
@@ -1,3 +1,5 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+
1
3
  export function getEnv(name: string, fallback?: any): any {
2
4
  const value = process.env[name]
3
5
  if (!value) {
package/src/index.ts CHANGED
@@ -4,6 +4,7 @@ export * from './db/mongo3'
4
4
  export * from './tw/utils'
5
5
  export * from './tw/wallet'
6
6
  export * from './auth'
7
+ export * from './chunk'
7
8
  export * from './env'
8
9
  export * from './parser'
9
10
  export * from './regex'
@@ -0,0 +1,48 @@
1
+ import { chunkByBytes } from '../src/chunk'
2
+
3
+ describe('chunkByBytes', () => {
4
+ test('splits array into chunks based on byte size', () => {
5
+ const arr = [
6
+ { id: 'a', val: 'x'.repeat(100) },
7
+ { id: 'b', val: 'y'.repeat(100) },
8
+ { id: 'c', val: 'z'.repeat(100) }
9
+ ]
10
+ const chunks = chunkByBytes(arr, 200) // 200 bytes max per chunk
11
+ expect(chunks.length).toBeGreaterThan(1) // should split
12
+ expect(chunks.flat()).toEqual(arr) // all items present
13
+ })
14
+
15
+ test('puts single large item in its own chunk', () => {
16
+ const arr = [{ id: 'big', val: 'x'.repeat(1000) }]
17
+ const chunks = chunkByBytes(arr, 100)
18
+ expect(chunks).toEqual([arr]) // large item pushed alone
19
+ })
20
+
21
+ test('does not split if all items fit within maxBytes', () => {
22
+ const arr = [
23
+ { id: 'a', val: 'x' },
24
+ { id: 'b', val: 'y' }
25
+ ]
26
+ const chunks = chunkByBytes(arr, 1000)
27
+ expect(chunks).toEqual([arr])
28
+ })
29
+
30
+ test('uses default maxBytes if not provided', () => {
31
+ const arr = [{ id: 'a', val: 'x'.repeat(10) }]
32
+ // call without maxBytes
33
+ const chunks = chunkByBytes(arr)
34
+ expect(chunks.flat()).toEqual(arr) // all items present
35
+ })
36
+
37
+ test('flushes current chunk when a single item exceeds maxBytes', () => {
38
+ const arr = [
39
+ { id: '1', val: 'x'.repeat(50) }, // first small item
40
+ { id: '2', val: 'y'.repeat(200) } // oversized item
41
+ ]
42
+ // set maxBytes small enough to trigger oversized item
43
+ const chunks = chunkByBytes(arr, 100)
44
+ expect(chunks.length).toBe(2) // first small chunk + oversized item alone
45
+ expect(chunks[0]).toEqual([arr[0]]) // first item in first chunk
46
+ expect(chunks[1]).toEqual([arr[1]]) // second item alone
47
+ })
48
+ })
@@ -1,4 +1,4 @@
1
- import { connectToMongo, connectToMongoWithUri, getCollection } from '../../src/db/mongo'
1
+ import { connectToMongo, connectToMongoWithUri, getCollection, getDb } from '../../src/db/mongo'
2
2
  import { MongoClient, Db } from 'mongodb'
3
3
  import * as secretsModule from '../../src/secrets'
4
4
 
@@ -37,18 +37,27 @@ describe('Mongo Utils', () => {
37
37
  expect(mockDb.collection).toHaveBeenCalledWith('users')
38
38
  })
39
39
 
40
- it('should throw error if db is not initialized', () => {
40
+ it('getDb should return the initialized Db instance', async () => {
41
+ await connectToMongo('test-project', 'mongo-uri-secret', 'test-db')
42
+ const got = getDb()
43
+ expect(got).toBe(mockDb)
44
+ })
45
+
46
+ it('should throw error if db is not initialized (getCollection/getDb)', () => {
41
47
  jest.isolateModules(() => {
48
+ // require a fresh copy of the module so module-level state is uninitialized
42
49
  // eslint-disable-next-line @typescript-eslint/no-require-imports
43
- const { getCollection } = require('../../src/db/mongo')
44
- expect(() => getCollection('users')).toThrow('Mongo not initialized')
50
+ const mod = require('../../src/db/mongo')
51
+ expect(() => mod.getCollection('users')).toThrow(/Mongo not initialized/)
52
+ expect(() => mod.getDb()).toThrow(/Mongo not initialized/)
45
53
  })
46
54
  })
47
55
  })
48
56
 
49
57
  describe('Mongo Utils 2', () => {
50
- it('should connect to MongoDB and store client/db', async () => {
51
- jest.isolateModules(async () => {
58
+ it('should connect to MongoDB and store client/db with URI helper', async () => {
59
+ // isolate modules so connect state is fresh for this test
60
+ await jest.isolateModulesAsync(async () => {
52
61
  // eslint-disable-next-line @typescript-eslint/no-require-imports
53
62
  const { connectToMongoWithUri } = require('../../src/db/mongo')
54
63
  await connectToMongoWithUri('mongo-uri', 'test-db')
@@ -58,10 +67,16 @@ describe('Mongo Utils 2', () => {
58
67
  })
59
68
  })
60
69
 
61
- it('should return a collection when db is initialized', async () => {
70
+ it('should return a collection when db is initialized (connectToMongoWithUri)', async () => {
62
71
  await connectToMongoWithUri('mongo-uri', 'test-db')
63
72
  getCollection('users')
64
73
 
65
74
  expect(mockDb.collection).toHaveBeenCalledWith('users')
66
75
  })
76
+
77
+ it('getDb should return the initialized Db instance after connectToMongoWithUri', async () => {
78
+ await connectToMongoWithUri('mongo-uri', 'test-db')
79
+ const got = getDb()
80
+ expect(got).toBe(mockDb)
81
+ })
67
82
  })