@8ms/helpers 3.0.13 → 3.0.15
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/AGENTS.md +110 -0
- package/CLAUDE.md +1 -0
- package/dist/drizzle/server/Drizzle.cjs +22 -21
- package/dist/drizzle/server/Drizzle.mjs +22 -21
- package/dist/stream/server/sort.cjs +15 -18
- package/dist/stream/server/sort.d.cts +13 -11
- package/dist/stream/server/sort.d.mts +13 -11
- package/dist/stream/server/sort.mjs +14 -18
- package/package.json +27 -32
package/AGENTS.md
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
Guidelines for AI coding agents working in this repository.
|
|
4
|
+
|
|
5
|
+
## What this repo is
|
|
6
|
+
|
|
7
|
+
`@8ms/helpers` is an internal TypeScript utility library published as an npm package. It wraps common operations (string, number, date, array, HTTP, environment detection) and provides thin, lazily-initialised clients for third-party services (AWS, Google Cloud, 1Password, OpenAI, Snapchat, etc.). It is **not** an application — there is no server to run and no UI to render.
|
|
8
|
+
|
|
9
|
+
## Build
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm run build # tsdown — compiles src/**/*.ts to dist/ as ESM + CJS with .d.ts
|
|
13
|
+
npm test # jest
|
|
14
|
+
npx tsc --noEmit # type-check only
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Output goes to `dist/`. Never commit `dist/` changes manually; the build generates them.
|
|
18
|
+
|
|
19
|
+
## Repository layout
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
src/
|
|
23
|
+
_class/ # BaseClass, BaseNamespace — all service clients extend BaseNamespace
|
|
24
|
+
api/ # HTTP helpers (get, post, deleteRequest) + ApiResponseClass
|
|
25
|
+
array/
|
|
26
|
+
boolean/
|
|
27
|
+
crud/
|
|
28
|
+
date/ # Luxon-based, UTC only
|
|
29
|
+
drizzle/ # ORM client (PlanetScale / MySQL / PostgreSQL)
|
|
30
|
+
environment/ # getEnvironment(), isVercel(), isDevelopment(), etc.
|
|
31
|
+
file/
|
|
32
|
+
geo/ # countries, languages data
|
|
33
|
+
googleCloud/ # BigQuery, Storage, Sheets, Google Ads
|
|
34
|
+
inngest/ # inngestState enum
|
|
35
|
+
json/
|
|
36
|
+
lodash/ # drop-in wrappers — no lodash runtime dependency
|
|
37
|
+
nextAuth/
|
|
38
|
+
nextJs/ # LazyLoad component, useAsyncEffect hook
|
|
39
|
+
number/
|
|
40
|
+
object/
|
|
41
|
+
onePassword/ # 1Password SDK client (server-only)
|
|
42
|
+
openAi/
|
|
43
|
+
prisma/
|
|
44
|
+
snapchat/
|
|
45
|
+
sorting/
|
|
46
|
+
stream/
|
|
47
|
+
string/
|
|
48
|
+
swr/ # SWR state helpers (client-only)
|
|
49
|
+
url/
|
|
50
|
+
util/ # defaultTo, getError, promiseChunks, sleep, etc.
|
|
51
|
+
webWorker/
|
|
52
|
+
xml/
|
|
53
|
+
aws/ # S3, SES, Lambda, EC2, SQS, SSM, Glue, ECS, CloudWatch
|
|
54
|
+
emsApi/ # internal 8MS API client
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Server-only code lives in `<module>/server/`, client-only in `<module>/client/`. Do not import server modules from client entry points or vice versa.
|
|
58
|
+
|
|
59
|
+
## Key patterns
|
|
60
|
+
|
|
61
|
+
**Service clients all extend `BaseNamespace`.** They expose an async `init(config)` method and lazy-load their SDK inside it. Do not instantiate the underlying SDK client at the top of the file — follow the existing pattern of dynamic `import()` inside `init`.
|
|
62
|
+
|
|
63
|
+
**`ApiResponseClass`** is the standard HTTP response wrapper used by all functions in `src/api/`. New HTTP helpers should return it and follow the existing IDLE/PENDING/SUCCESS/ERROR state pattern.
|
|
64
|
+
|
|
65
|
+
**No bundling.** `tsdown` outputs unbundled files. Every source file maps to a dist file. Do not introduce barrel re-exports that would force consumers to load unrelated code.
|
|
66
|
+
|
|
67
|
+
**Peer dependencies.** AWS SDK, Google Cloud SDK, Prisma, Drizzle, Next.js, React — all are peer deps. Never add them as direct dependencies. Import them only inside `init()` or behind a dynamic import so consumers who don't use that module pay no cost.
|
|
68
|
+
|
|
69
|
+
**TypeScript target is ES2024, module resolution is `bundler`.** Use native ES features freely. No CommonJS patterns in source files.
|
|
70
|
+
|
|
71
|
+
**No comments by default.** Only add a comment when the *why* is non-obvious (a workaround, a hidden constraint). Do not document what the code does — naming should do that.
|
|
72
|
+
|
|
73
|
+
## Adding a new module
|
|
74
|
+
|
|
75
|
+
1. Create `src/<name>/` with an `index.ts` re-exporting the public surface.
|
|
76
|
+
2. If the module has a server and a client variant, use `src/<name>/server/` and `src/<name>/client/` subdirectories with their own `index.ts`.
|
|
77
|
+
3. If the module wraps a third-party SDK, extend `BaseNamespace` and lazy-load the SDK inside `init()`.
|
|
78
|
+
4. Do not add the SDK as a direct dependency — add it as a peer dependency in `package.json`.
|
|
79
|
+
5. Export the new module from the relevant top-level entry point (`src/aws/server/index.ts`, etc.) or create a new one if the module stands alone.
|
|
80
|
+
|
|
81
|
+
## Adding a new service method
|
|
82
|
+
|
|
83
|
+
Follow the existing pattern in the relevant class. For example, when adding a method to `OnePassword`:
|
|
84
|
+
- Update methods take the full item URL, fetch the item with `getItem(url)`, mutate it, then call `this.client.items.put(item)`.
|
|
85
|
+
- Create methods take a vault URL (to extract `vaultId` via `getIdsFromUrl`) plus a `title` and content value.
|
|
86
|
+
- Use `ItemCategory.SecureNote` for secure note items.
|
|
87
|
+
|
|
88
|
+
## Testing
|
|
89
|
+
|
|
90
|
+
Tests live alongside source as `*.test.ts`. Run with `npm test`. Coverage is collected but not enforced at a threshold — add tests for any pure utility functions you introduce. Service client methods (AWS, Google Cloud, etc.) are not tested; do not mock them.
|
|
91
|
+
|
|
92
|
+
## Environment variables
|
|
93
|
+
|
|
94
|
+
The library reads these at runtime — do not hardcode them:
|
|
95
|
+
|
|
96
|
+
| Variable | Used by |
|
|
97
|
+
| --- | --- |
|
|
98
|
+
| `EMS_ENVIRONMENT` | `getEnvironment()` |
|
|
99
|
+
| `NEXT_PUBLIC_EMS_ENVIRONMENT` | `getEnvironment()` in Next.js |
|
|
100
|
+
| `VERCEL_GIT_COMMIT_REF` | `getEnvironment()` on Vercel |
|
|
101
|
+
|
|
102
|
+
AWS and GCP credentials are passed explicitly via `init(config)` — the library does not read `AWS_*` or `GOOGLE_*` env vars directly.
|
|
103
|
+
|
|
104
|
+
## What to avoid
|
|
105
|
+
|
|
106
|
+
- Do not alter `tsconfig.json` or `tsdown.config.ts` without a clear reason — the build pipeline is intentional.
|
|
107
|
+
- Do not add runtime dependencies that duplicate an existing peer dependency.
|
|
108
|
+
- Do not use `any` except where the public API genuinely accepts arbitrary JSON (e.g. `setJsonNote`, `createJsonNote`).
|
|
109
|
+
- Do not introduce default exports — everything is named.
|
|
110
|
+
- Do not run `npm run build` as a validation step; use `npx tsc --noEmit` to type-check only.
|
package/CLAUDE.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@AGENTS.md
|
|
@@ -6,38 +6,38 @@ var Drizzle = class extends require__class_BaseNamespace.BaseNamespace {
|
|
|
6
6
|
init = async (config) => {
|
|
7
7
|
if (!this.client) {
|
|
8
8
|
let logger = void 0;
|
|
9
|
-
if (
|
|
9
|
+
if (true === config?.isDebug) {
|
|
10
10
|
const { DefaultLogger } = await import("drizzle-orm/logger");
|
|
11
11
|
logger = new DefaultLogger();
|
|
12
12
|
}
|
|
13
13
|
let casing = void 0;
|
|
14
|
-
if ("snake" ===
|
|
15
|
-
else if ("camel" ===
|
|
16
|
-
if (
|
|
14
|
+
if ("snake" === config?.casing) casing = "snake_case";
|
|
15
|
+
else if ("camel" === config?.casing) casing = "camelCase";
|
|
16
|
+
if (true === config?.isPlanetScale) try {
|
|
17
17
|
const { drizzle } = await import("drizzle-orm/planetscale-serverless");
|
|
18
18
|
this.client = drizzle({
|
|
19
19
|
casing,
|
|
20
|
-
connection: { url:
|
|
21
|
-
relations:
|
|
22
|
-
schema:
|
|
20
|
+
connection: { url: config?.url },
|
|
21
|
+
relations: config?.relations,
|
|
22
|
+
schema: config?.schema,
|
|
23
23
|
logger
|
|
24
24
|
});
|
|
25
25
|
} catch (e) {
|
|
26
26
|
throw new Error(`PlanetScale driver not installed - ${require_util_getError.getError(e)}`);
|
|
27
27
|
}
|
|
28
|
-
else if (
|
|
28
|
+
else if (true === config?.isMysql) try {
|
|
29
29
|
const { drizzle } = await import("drizzle-orm/mysql2");
|
|
30
30
|
const pool = (await import("mysql2/promise")).createPool({
|
|
31
|
-
uri:
|
|
32
|
-
connectionLimit:
|
|
33
|
-
idleTimeout:
|
|
34
|
-
connectTimeout:
|
|
31
|
+
uri: config.url,
|
|
32
|
+
connectionLimit: config.pool?.max ?? 10,
|
|
33
|
+
idleTimeout: config.pool?.idleTimeoutMs ?? 3e4,
|
|
34
|
+
connectTimeout: config.pool?.connectTimeoutMs ?? 5e3,
|
|
35
35
|
waitForConnections: true,
|
|
36
36
|
queueLimit: 0
|
|
37
37
|
});
|
|
38
38
|
this.client = drizzle(pool, {
|
|
39
|
-
schema:
|
|
40
|
-
relations:
|
|
39
|
+
schema: config.schema,
|
|
40
|
+
relations: config.relations,
|
|
41
41
|
casing,
|
|
42
42
|
logger,
|
|
43
43
|
mode: "default"
|
|
@@ -45,18 +45,18 @@ var Drizzle = class extends require__class_BaseNamespace.BaseNamespace {
|
|
|
45
45
|
} catch (e) {
|
|
46
46
|
throw new Error(`MySQL2 driver not installed - ${require_util_getError.getError(e)}`);
|
|
47
47
|
}
|
|
48
|
-
else if (
|
|
48
|
+
else if (true === config?.isPostgres) try {
|
|
49
49
|
const { drizzle } = await import("drizzle-orm/node-postgres");
|
|
50
50
|
const { Pool } = await import("pg");
|
|
51
51
|
const pool = new Pool({
|
|
52
|
-
connectionString:
|
|
53
|
-
max:
|
|
54
|
-
idleTimeoutMillis:
|
|
55
|
-
connectionTimeoutMillis:
|
|
52
|
+
connectionString: config.url,
|
|
53
|
+
max: config.pool?.max ?? 10,
|
|
54
|
+
idleTimeoutMillis: config.pool?.idleTimeoutMs ?? 3e4,
|
|
55
|
+
connectionTimeoutMillis: config.pool?.connectTimeoutMs ?? 5e3
|
|
56
56
|
});
|
|
57
57
|
this.client = drizzle(pool, {
|
|
58
|
-
schema:
|
|
59
|
-
relations:
|
|
58
|
+
schema: config.schema,
|
|
59
|
+
relations: config.relations,
|
|
60
60
|
casing,
|
|
61
61
|
logger
|
|
62
62
|
});
|
|
@@ -64,6 +64,7 @@ var Drizzle = class extends require__class_BaseNamespace.BaseNamespace {
|
|
|
64
64
|
throw new Error(`Postgres (pg) driver not installed - ${require_util_getError.getError(e)}`);
|
|
65
65
|
}
|
|
66
66
|
else throw new Error(`No database type configured`);
|
|
67
|
+
this.config = config;
|
|
67
68
|
}
|
|
68
69
|
return this;
|
|
69
70
|
};
|
|
@@ -5,38 +5,38 @@ var Drizzle = class extends BaseNamespace {
|
|
|
5
5
|
init = async (config) => {
|
|
6
6
|
if (!this.client) {
|
|
7
7
|
let logger = void 0;
|
|
8
|
-
if (
|
|
8
|
+
if (true === config?.isDebug) {
|
|
9
9
|
const { DefaultLogger } = await import("drizzle-orm/logger");
|
|
10
10
|
logger = new DefaultLogger();
|
|
11
11
|
}
|
|
12
12
|
let casing = void 0;
|
|
13
|
-
if ("snake" ===
|
|
14
|
-
else if ("camel" ===
|
|
15
|
-
if (
|
|
13
|
+
if ("snake" === config?.casing) casing = "snake_case";
|
|
14
|
+
else if ("camel" === config?.casing) casing = "camelCase";
|
|
15
|
+
if (true === config?.isPlanetScale) try {
|
|
16
16
|
const { drizzle } = await import("drizzle-orm/planetscale-serverless");
|
|
17
17
|
this.client = drizzle({
|
|
18
18
|
casing,
|
|
19
|
-
connection: { url:
|
|
20
|
-
relations:
|
|
21
|
-
schema:
|
|
19
|
+
connection: { url: config?.url },
|
|
20
|
+
relations: config?.relations,
|
|
21
|
+
schema: config?.schema,
|
|
22
22
|
logger
|
|
23
23
|
});
|
|
24
24
|
} catch (e) {
|
|
25
25
|
throw new Error(`PlanetScale driver not installed - ${getError(e)}`);
|
|
26
26
|
}
|
|
27
|
-
else if (
|
|
27
|
+
else if (true === config?.isMysql) try {
|
|
28
28
|
const { drizzle } = await import("drizzle-orm/mysql2");
|
|
29
29
|
const pool = (await import("mysql2/promise")).createPool({
|
|
30
|
-
uri:
|
|
31
|
-
connectionLimit:
|
|
32
|
-
idleTimeout:
|
|
33
|
-
connectTimeout:
|
|
30
|
+
uri: config.url,
|
|
31
|
+
connectionLimit: config.pool?.max ?? 10,
|
|
32
|
+
idleTimeout: config.pool?.idleTimeoutMs ?? 3e4,
|
|
33
|
+
connectTimeout: config.pool?.connectTimeoutMs ?? 5e3,
|
|
34
34
|
waitForConnections: true,
|
|
35
35
|
queueLimit: 0
|
|
36
36
|
});
|
|
37
37
|
this.client = drizzle(pool, {
|
|
38
|
-
schema:
|
|
39
|
-
relations:
|
|
38
|
+
schema: config.schema,
|
|
39
|
+
relations: config.relations,
|
|
40
40
|
casing,
|
|
41
41
|
logger,
|
|
42
42
|
mode: "default"
|
|
@@ -44,18 +44,18 @@ var Drizzle = class extends BaseNamespace {
|
|
|
44
44
|
} catch (e) {
|
|
45
45
|
throw new Error(`MySQL2 driver not installed - ${getError(e)}`);
|
|
46
46
|
}
|
|
47
|
-
else if (
|
|
47
|
+
else if (true === config?.isPostgres) try {
|
|
48
48
|
const { drizzle } = await import("drizzle-orm/node-postgres");
|
|
49
49
|
const { Pool } = await import("pg");
|
|
50
50
|
const pool = new Pool({
|
|
51
|
-
connectionString:
|
|
52
|
-
max:
|
|
53
|
-
idleTimeoutMillis:
|
|
54
|
-
connectionTimeoutMillis:
|
|
51
|
+
connectionString: config.url,
|
|
52
|
+
max: config.pool?.max ?? 10,
|
|
53
|
+
idleTimeoutMillis: config.pool?.idleTimeoutMs ?? 3e4,
|
|
54
|
+
connectionTimeoutMillis: config.pool?.connectTimeoutMs ?? 5e3
|
|
55
55
|
});
|
|
56
56
|
this.client = drizzle(pool, {
|
|
57
|
-
schema:
|
|
58
|
-
relations:
|
|
57
|
+
schema: config.schema,
|
|
58
|
+
relations: config.relations,
|
|
59
59
|
casing,
|
|
60
60
|
logger
|
|
61
61
|
});
|
|
@@ -63,6 +63,7 @@ var Drizzle = class extends BaseNamespace {
|
|
|
63
63
|
throw new Error(`Postgres (pg) driver not installed - ${getError(e)}`);
|
|
64
64
|
}
|
|
65
65
|
else throw new Error(`No database type configured`);
|
|
66
|
+
this.config = config;
|
|
66
67
|
}
|
|
67
68
|
return this;
|
|
68
69
|
};
|
|
@@ -1,46 +1,43 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
let node_stream = require("node:stream");
|
|
2
3
|
//#region src/stream/server/sort.ts
|
|
3
|
-
const Transform = require("stream").Transform;
|
|
4
4
|
const batch = 15e3;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
var SortStreamer = class extends node_stream.Transform {
|
|
6
|
+
a;
|
|
7
|
+
i;
|
|
8
|
+
k;
|
|
9
|
+
currentSize;
|
|
10
|
+
sortedArray;
|
|
11
|
+
comp;
|
|
10
12
|
constructor(options, comp) {
|
|
11
13
|
super(options);
|
|
12
14
|
this.a = new Array(batch);
|
|
13
15
|
this.i = 0;
|
|
14
16
|
this.k = 0;
|
|
15
17
|
this.currentSize = batch;
|
|
16
|
-
this.isDone = false;
|
|
17
18
|
this.sortedArray = void 0;
|
|
18
19
|
this.comp = comp;
|
|
19
20
|
}
|
|
20
21
|
_transform(data, _, callback) {
|
|
21
22
|
if (data) {
|
|
22
23
|
this.a[this.i++] = data;
|
|
23
|
-
if (this.i
|
|
24
|
-
this.currentSize
|
|
25
|
-
|
|
26
|
-
for (
|
|
24
|
+
if (this.i === this.currentSize) {
|
|
25
|
+
this.currentSize *= 2;
|
|
26
|
+
const tmp = new Array(this.currentSize);
|
|
27
|
+
for (let j = 0; j < this.i; j++) tmp[j] = this.a[j];
|
|
27
28
|
this.a = tmp;
|
|
28
29
|
}
|
|
29
30
|
}
|
|
30
31
|
callback();
|
|
31
32
|
}
|
|
32
|
-
_flush() {
|
|
33
|
+
_flush(callback) {
|
|
33
34
|
this.sortedArray = this.a.slice(0, this.i).sort(this.comp);
|
|
34
|
-
this.fullflush();
|
|
35
|
-
}
|
|
36
|
-
fullflush() {
|
|
37
35
|
while (this.k < this.i) this.push(this.sortedArray[this.k++]);
|
|
38
|
-
|
|
36
|
+
callback();
|
|
39
37
|
}
|
|
40
38
|
};
|
|
41
39
|
const sort = (comp, options) => {
|
|
42
|
-
|
|
43
|
-
return new SortStreamer(options, comp);
|
|
40
|
+
return new SortStreamer(options ?? { objectMode: true }, comp);
|
|
44
41
|
};
|
|
45
42
|
//#endregion
|
|
46
43
|
exports.sort = sort;
|
|
@@ -1,15 +1,17 @@
|
|
|
1
|
+
import { Transform, TransformCallback, TransformOptions } from "node:stream";
|
|
2
|
+
|
|
1
3
|
//#region src/stream/server/sort.d.ts
|
|
2
|
-
declare
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
4
|
+
declare class SortStreamer<T> extends Transform {
|
|
5
|
+
private a;
|
|
6
|
+
private i;
|
|
7
|
+
private k;
|
|
8
|
+
private currentSize;
|
|
9
|
+
private sortedArray;
|
|
10
|
+
private readonly comp;
|
|
11
|
+
constructor(options: TransformOptions, comp: (a: T, b: T) => number);
|
|
12
|
+
_transform(data: T, _: BufferEncoding, callback: TransformCallback): void;
|
|
13
|
+
_flush(callback: TransformCallback): void;
|
|
12
14
|
}
|
|
13
|
-
declare const sort: (comp:
|
|
15
|
+
declare const sort: <T>(comp: (a: T, b: T) => number, options?: TransformOptions) => SortStreamer<T>;
|
|
14
16
|
//#endregion
|
|
15
17
|
export { sort };
|
|
@@ -1,15 +1,17 @@
|
|
|
1
|
+
import { Transform, TransformCallback, TransformOptions } from "node:stream";
|
|
2
|
+
|
|
1
3
|
//#region src/stream/server/sort.d.ts
|
|
2
|
-
declare
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
4
|
+
declare class SortStreamer<T> extends Transform {
|
|
5
|
+
private a;
|
|
6
|
+
private i;
|
|
7
|
+
private k;
|
|
8
|
+
private currentSize;
|
|
9
|
+
private sortedArray;
|
|
10
|
+
private readonly comp;
|
|
11
|
+
constructor(options: TransformOptions, comp: (a: T, b: T) => number);
|
|
12
|
+
_transform(data: T, _: BufferEncoding, callback: TransformCallback): void;
|
|
13
|
+
_flush(callback: TransformCallback): void;
|
|
12
14
|
}
|
|
13
|
-
declare const sort: (comp:
|
|
15
|
+
declare const sort: <T>(comp: (a: T, b: T) => number, options?: TransformOptions) => SortStreamer<T>;
|
|
14
16
|
//#endregion
|
|
15
17
|
export { sort };
|
|
@@ -1,46 +1,42 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Transform } from "node:stream";
|
|
2
2
|
//#region src/stream/server/sort.ts
|
|
3
|
-
const Transform = __require("stream").Transform;
|
|
4
3
|
const batch = 15e3;
|
|
5
|
-
/**
|
|
6
|
-
* Batch sort stream without overloading the memory limit.
|
|
7
|
-
* https://www.npmjs.com/package/fast-stream-sort
|
|
8
|
-
*/
|
|
9
4
|
var SortStreamer = class extends Transform {
|
|
5
|
+
a;
|
|
6
|
+
i;
|
|
7
|
+
k;
|
|
8
|
+
currentSize;
|
|
9
|
+
sortedArray;
|
|
10
|
+
comp;
|
|
10
11
|
constructor(options, comp) {
|
|
11
12
|
super(options);
|
|
12
13
|
this.a = new Array(batch);
|
|
13
14
|
this.i = 0;
|
|
14
15
|
this.k = 0;
|
|
15
16
|
this.currentSize = batch;
|
|
16
|
-
this.isDone = false;
|
|
17
17
|
this.sortedArray = void 0;
|
|
18
18
|
this.comp = comp;
|
|
19
19
|
}
|
|
20
20
|
_transform(data, _, callback) {
|
|
21
21
|
if (data) {
|
|
22
22
|
this.a[this.i++] = data;
|
|
23
|
-
if (this.i
|
|
24
|
-
this.currentSize
|
|
25
|
-
|
|
26
|
-
for (
|
|
23
|
+
if (this.i === this.currentSize) {
|
|
24
|
+
this.currentSize *= 2;
|
|
25
|
+
const tmp = new Array(this.currentSize);
|
|
26
|
+
for (let j = 0; j < this.i; j++) tmp[j] = this.a[j];
|
|
27
27
|
this.a = tmp;
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
callback();
|
|
31
31
|
}
|
|
32
|
-
_flush() {
|
|
32
|
+
_flush(callback) {
|
|
33
33
|
this.sortedArray = this.a.slice(0, this.i).sort(this.comp);
|
|
34
|
-
this.fullflush();
|
|
35
|
-
}
|
|
36
|
-
fullflush() {
|
|
37
34
|
while (this.k < this.i) this.push(this.sortedArray[this.k++]);
|
|
38
|
-
|
|
35
|
+
callback();
|
|
39
36
|
}
|
|
40
37
|
};
|
|
41
38
|
const sort = (comp, options) => {
|
|
42
|
-
|
|
43
|
-
return new SortStreamer(options, comp);
|
|
39
|
+
return new SortStreamer(options ?? { objectMode: true }, comp);
|
|
44
40
|
};
|
|
45
41
|
//#endregion
|
|
46
42
|
export { sort };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@8ms/helpers",
|
|
3
3
|
"license": "UNLICENSED",
|
|
4
|
-
"version": "3.0.
|
|
4
|
+
"version": "3.0.15",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/8millionstories-organisation/8ms-helpers-ts.git"
|
|
@@ -51,7 +51,6 @@
|
|
|
51
51
|
"pg": "^8.0.0",
|
|
52
52
|
"react": "^19.0.0",
|
|
53
53
|
"react-intersection-observer": "^10.0.0",
|
|
54
|
-
"stream-chain": "^3.0.0",
|
|
55
54
|
"swr": "^2.0.0"
|
|
56
55
|
},
|
|
57
56
|
"peerDependenciesMeta": {
|
|
@@ -154,35 +153,32 @@
|
|
|
154
153
|
"react": {
|
|
155
154
|
"optional": true
|
|
156
155
|
},
|
|
157
|
-
"stream-chain": {
|
|
158
|
-
"optional": true
|
|
159
|
-
},
|
|
160
156
|
"swr": {
|
|
161
157
|
"optional": true
|
|
162
158
|
}
|
|
163
159
|
},
|
|
164
160
|
"devDependencies": {
|
|
165
161
|
"@1password/sdk": "^0.4.0",
|
|
166
|
-
"@aws-sdk/client-cloudwatch": "^3.
|
|
167
|
-
"@aws-sdk/client-cloudwatch-logs": "^3.
|
|
168
|
-
"@aws-sdk/client-ec2": "^3.
|
|
169
|
-
"@aws-sdk/client-ecs": "^3.
|
|
170
|
-
"@aws-sdk/client-glue": "^3.
|
|
171
|
-
"@aws-sdk/client-lambda": "^3.
|
|
172
|
-
"@aws-sdk/client-s3": "^3.
|
|
173
|
-
"@aws-sdk/client-ses": "^3.
|
|
174
|
-
"@aws-sdk/client-sqs": "^3.
|
|
175
|
-
"@aws-sdk/client-ssm": "^3.
|
|
176
|
-
"@aws-sdk/lib-storage": "^3.
|
|
177
|
-
"@aws-sdk/s3-request-presigner": "^3.
|
|
178
|
-
"@aws-sdk/types": "^3.973.
|
|
162
|
+
"@aws-sdk/client-cloudwatch": "^3.1068.0",
|
|
163
|
+
"@aws-sdk/client-cloudwatch-logs": "^3.1068.0",
|
|
164
|
+
"@aws-sdk/client-ec2": "^3.1068.0",
|
|
165
|
+
"@aws-sdk/client-ecs": "^3.1068.0",
|
|
166
|
+
"@aws-sdk/client-glue": "^3.1068.0",
|
|
167
|
+
"@aws-sdk/client-lambda": "^3.1068.0",
|
|
168
|
+
"@aws-sdk/client-s3": "^3.1068.0",
|
|
169
|
+
"@aws-sdk/client-ses": "^3.1068.0",
|
|
170
|
+
"@aws-sdk/client-sqs": "^3.1068.0",
|
|
171
|
+
"@aws-sdk/client-ssm": "^3.1068.0",
|
|
172
|
+
"@aws-sdk/lib-storage": "^3.1068.0",
|
|
173
|
+
"@aws-sdk/s3-request-presigner": "^3.1068.0",
|
|
174
|
+
"@aws-sdk/types": "^3.973.12",
|
|
179
175
|
"@babel/core": "7.29.7",
|
|
180
176
|
"@babel/preset-env": "7.29.7",
|
|
181
177
|
"@babel/preset-flow": "7.29.7",
|
|
182
178
|
"@babel/preset-typescript": "7.29.7",
|
|
183
179
|
"@google-cloud/bigquery": "^8.3.1",
|
|
184
|
-
"@google-cloud/common": "^6.0.
|
|
185
|
-
"@google-cloud/storage": "^7.
|
|
180
|
+
"@google-cloud/common": "^6.0.1",
|
|
181
|
+
"@google-cloud/storage": "^7.21.0",
|
|
186
182
|
"@googleapis/sheets": "^13.0.2",
|
|
187
183
|
"@planetscale/database": "^1.20.1",
|
|
188
184
|
"@prisma/adapter-mariadb": "^7.8.0",
|
|
@@ -193,27 +189,26 @@
|
|
|
193
189
|
"@types/fs-extra": "^11.0.4",
|
|
194
190
|
"@types/jest": "30.0.0",
|
|
195
191
|
"@types/luxon": "3.7.1",
|
|
196
|
-
"@types/node": "^24.
|
|
197
|
-
"@types/react": "^19.2.
|
|
198
|
-
"@vercel/oidc": "^3.
|
|
199
|
-
"@vercel/oidc-aws-credentials-provider": "^3.1.
|
|
192
|
+
"@types/node": "^24.13.2",
|
|
193
|
+
"@types/react": "^19.2.17",
|
|
194
|
+
"@vercel/oidc": "^3.6.1",
|
|
195
|
+
"@vercel/oidc-aws-credentials-provider": "^3.1.4",
|
|
200
196
|
"babel-jest": "30.4.1",
|
|
201
197
|
"dotenv": "^17.4.2",
|
|
202
198
|
"drizzle-orm": "beta",
|
|
203
199
|
"fs-extra": "^11.3.5",
|
|
204
|
-
"gaxios": "^7.1.
|
|
205
|
-
"google-auth-library": "^10.
|
|
206
|
-
"googleapis-common": "^8.0.
|
|
200
|
+
"gaxios": "^7.1.5",
|
|
201
|
+
"google-auth-library": "^10.7.0",
|
|
202
|
+
"googleapis-common": "^8.0.2",
|
|
207
203
|
"jest": "^30.4.2",
|
|
208
|
-
"mysql2": "^3.22.
|
|
209
|
-
"next": "^16.2.
|
|
204
|
+
"mysql2": "^3.22.5",
|
|
205
|
+
"next": "^16.2.9",
|
|
210
206
|
"pg": "^8.21.0",
|
|
211
|
-
"react": "^19.2.
|
|
207
|
+
"react": "^19.2.7",
|
|
212
208
|
"react-intersection-observer": "^10.0.3",
|
|
213
|
-
"stream-chain": "^3.6.3",
|
|
214
209
|
"swr": "^2.4.1",
|
|
215
210
|
"ts-node": "^10.9.2",
|
|
216
|
-
"tsdown": "^0.22.
|
|
211
|
+
"tsdown": "^0.22.2",
|
|
217
212
|
"tslib": "^2.8.1",
|
|
218
213
|
"typescript": "^6.0.3"
|
|
219
214
|
},
|