@t4h.framework/fs 0.13.0 → 0.14.0
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/.ai/skills/framework-fs/SKILL.md +87 -186
- package/.ai/skills/framework-fs-split/SKILL.md +134 -314
- package/.ai/skills/framework-fs-write/SKILL.md +54 -214
- package/CHANGELOG.md +56 -0
- package/README.md +20 -351
- package/dist/activities/FileJoinActivity.d.ts +4 -5
- package/dist/activities/FileJoinActivity.d.ts.map +1 -1
- package/dist/activities/FileJoinActivity.js +38 -43
- package/dist/activities/FileJoinActivity.js.map +1 -1
- package/dist/activities/FileReadActivity.d.ts +1 -0
- package/dist/activities/FileReadActivity.d.ts.map +1 -1
- package/dist/activities/FileReadActivity.js +34 -26
- package/dist/activities/FileReadActivity.js.map +1 -1
- package/dist/activities/FileSplitActivity.d.ts +23 -43
- package/dist/activities/FileSplitActivity.d.ts.map +1 -1
- package/dist/activities/FileSplitActivity.js +23 -38
- package/dist/activities/FileSplitActivity.js.map +1 -1
- package/dist/constants/operations.d.ts +1 -1
- package/dist/constants/operations.d.ts.map +1 -1
- package/dist/constants/operations.js +3 -14
- package/dist/constants/operations.js.map +1 -1
- package/dist/fs.d.ts +5 -1
- package/dist/fs.d.ts.map +1 -1
- package/dist/helpers/CSV.d.ts +2 -2
- package/dist/helpers/CSV.d.ts.map +1 -1
- package/dist/helpers/CSV.js +20 -22
- package/dist/helpers/CSV.js.map +1 -1
- package/dist/helpers/group-by-key.d.ts +8 -0
- package/dist/helpers/group-by-key.d.ts.map +1 -0
- package/dist/helpers/group-by-key.js +35 -0
- package/dist/helpers/group-by-key.js.map +1 -0
- package/dist/helpers/group-records.d.ts +2 -2
- package/dist/helpers/group-records.d.ts.map +1 -1
- package/dist/helpers/group-records.js +3 -3
- package/dist/helpers/group-records.js.map +1 -1
- package/dist/helpers/in-chunks.d.ts +5 -0
- package/dist/helpers/in-chunks.d.ts.map +1 -0
- package/dist/helpers/in-chunks.js +17 -0
- package/dist/helpers/in-chunks.js.map +1 -0
- package/dist/helpers/split-records.d.ts +4 -3
- package/dist/helpers/split-records.d.ts.map +1 -1
- package/dist/helpers/split-records.js +75 -46
- package/dist/helpers/split-records.js.map +1 -1
- package/dist/helpers/where-matcher.d.ts +21 -0
- package/dist/helpers/where-matcher.d.ts.map +1 -0
- package/dist/helpers/where-matcher.js +11 -0
- package/dist/helpers/where-matcher.js.map +1 -0
- package/dist/models/BinaryRecordKey.d.ts +27 -0
- package/dist/models/BinaryRecordKey.d.ts.map +1 -0
- package/dist/models/BinaryRecordKey.js +52 -0
- package/dist/models/BinaryRecordKey.js.map +1 -0
- package/dist/models/BinarySource.d.ts +45 -0
- package/dist/models/BinarySource.d.ts.map +1 -0
- package/dist/models/BinarySource.js +58 -0
- package/dist/models/BinarySource.js.map +1 -0
- package/dist/models/BinarySplit.d.ts +45 -0
- package/dist/models/BinarySplit.d.ts.map +1 -0
- package/dist/models/BinarySplit.js +81 -0
- package/dist/models/BinarySplit.js.map +1 -0
- package/dist/models/BinarySplitInput.d.ts +21 -0
- package/dist/models/BinarySplitInput.d.ts.map +1 -0
- package/dist/models/BinarySplitInput.js +85 -0
- package/dist/models/BinarySplitInput.js.map +1 -0
- package/dist/models/Database.d.ts +15 -0
- package/dist/models/Database.d.ts.map +1 -0
- package/dist/models/Database.js +57 -0
- package/dist/models/Database.js.map +1 -0
- package/dist/models/OpenKeyGroup.d.ts +23 -0
- package/dist/models/OpenKeyGroup.d.ts.map +1 -0
- package/dist/models/OpenKeyGroup.js +42 -0
- package/dist/models/OpenKeyGroup.js.map +1 -0
- package/dist/models/SplitDatabaseWorker.d.ts +12 -0
- package/dist/models/SplitDatabaseWorker.d.ts.map +1 -0
- package/dist/models/SplitDatabaseWorker.js +65 -0
- package/dist/models/SplitDatabaseWorker.js.map +1 -0
- package/dist/workers/split-database.d.ts +10 -0
- package/dist/workers/split-database.d.ts.map +1 -0
- package/dist/workers/split-database.js +43 -0
- package/dist/workers/split-database.js.map +1 -0
- package/package.json +5 -4
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
const MARKER = '@t4h.framework/fs:split:';
|
|
2
|
+
export const SLICE_MARKER = `${MARKER}slice`;
|
|
3
|
+
export const KEY_MARKER = `${MARKER}key`;
|
|
4
|
+
export const ROWS_MARKER = `${MARKER}rows:`;
|
|
5
|
+
function markerOf(text) {
|
|
6
|
+
if (!text.includes(MARKER))
|
|
7
|
+
return undefined;
|
|
8
|
+
if (text === SLICE_MARKER)
|
|
9
|
+
return { kind: 'slice' };
|
|
10
|
+
if (text === KEY_MARKER)
|
|
11
|
+
return { kind: 'key' };
|
|
12
|
+
if (text.startsWith(ROWS_MARKER))
|
|
13
|
+
return { kind: 'rows', name: text.slice(ROWS_MARKER.length) };
|
|
14
|
+
return { kind: 'changed' };
|
|
15
|
+
}
|
|
16
|
+
function isPlainObject(value) {
|
|
17
|
+
if (value === null)
|
|
18
|
+
return false;
|
|
19
|
+
if (typeof value !== 'object')
|
|
20
|
+
return false;
|
|
21
|
+
const prototype = Object.getPrototypeOf(value);
|
|
22
|
+
return prototype === Object.prototype || prototype === null;
|
|
23
|
+
}
|
|
24
|
+
function markersOf(value) {
|
|
25
|
+
if (typeof value === 'string') {
|
|
26
|
+
const marker = markerOf(value);
|
|
27
|
+
return marker ? [marker] : [];
|
|
28
|
+
}
|
|
29
|
+
if (Array.isArray(value))
|
|
30
|
+
return value.flatMap(markersOf);
|
|
31
|
+
if (!isPlainObject(value))
|
|
32
|
+
return [];
|
|
33
|
+
return Object.values(value).flatMap(markersOf);
|
|
34
|
+
}
|
|
35
|
+
function fillText(text, values) {
|
|
36
|
+
const marker = markerOf(text);
|
|
37
|
+
switch (marker?.kind) {
|
|
38
|
+
case 'slice':
|
|
39
|
+
return values.slice;
|
|
40
|
+
case 'key':
|
|
41
|
+
return values.key ?? '';
|
|
42
|
+
case 'rows':
|
|
43
|
+
return values.rows?.[marker.name] ?? '';
|
|
44
|
+
case 'changed':
|
|
45
|
+
case undefined:
|
|
46
|
+
return text;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function fill(value, values) {
|
|
50
|
+
if (typeof value === 'string')
|
|
51
|
+
return fillText(value, values);
|
|
52
|
+
if (Array.isArray(value))
|
|
53
|
+
return value.map((item) => fill(item, values));
|
|
54
|
+
if (!isPlainObject(value))
|
|
55
|
+
return value;
|
|
56
|
+
return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, fill(item, values)]));
|
|
57
|
+
}
|
|
58
|
+
export class BinarySplitInput {
|
|
59
|
+
template;
|
|
60
|
+
constructor(template) {
|
|
61
|
+
this.template = template;
|
|
62
|
+
}
|
|
63
|
+
static from(template, { isGrouped, sources }) {
|
|
64
|
+
const markers = markersOf(template);
|
|
65
|
+
const missingSource = markers
|
|
66
|
+
.flatMap(marker => (marker.kind === 'rows' ? [marker.name] : []))
|
|
67
|
+
.find(name => !sources.includes(name));
|
|
68
|
+
if (markers.length === 0)
|
|
69
|
+
throw new TypeError('Split input must place Split.slice, Split.key or Split.rows as they are, alone or inside plain objects and arrays');
|
|
70
|
+
if (markers.some(marker => marker.kind === 'changed'))
|
|
71
|
+
throw new TypeError('Split input changes a marker: place Split.slice, Split.key and Split.rows as they are');
|
|
72
|
+
if (!isGrouped && markers.some(marker => marker.kind !== 'slice'))
|
|
73
|
+
throw new TypeError('Split input uses Split.key or Split.rows without groupBy');
|
|
74
|
+
if (missingSource !== undefined)
|
|
75
|
+
throw new TypeError(`Split input uses Split.rows('${missingSource}'), which is not in with`);
|
|
76
|
+
return new BinarySplitInput(template);
|
|
77
|
+
}
|
|
78
|
+
toJSON() {
|
|
79
|
+
return this.template;
|
|
80
|
+
}
|
|
81
|
+
fill(values) {
|
|
82
|
+
return fill(this.template, values);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=BinarySplitInput.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BinarySplitInput.js","sourceRoot":"","sources":["../../src/models/BinarySplitInput.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type SQLInputValue } from 'node:sqlite';
|
|
2
|
+
export type DatabaseRow = Record<string, SQLInputValue>;
|
|
3
|
+
export declare class Database {
|
|
4
|
+
private readonly db;
|
|
5
|
+
private readonly statements;
|
|
6
|
+
private constructor();
|
|
7
|
+
static open(file: string): Database;
|
|
8
|
+
exec(sql: string): void;
|
|
9
|
+
insert(table: string, rows: DatabaseRow[]): void;
|
|
10
|
+
run(sql: string, rows: DatabaseRow[]): void;
|
|
11
|
+
select<Row>(sql: string, ...params: SQLInputValue[]): Iterable<Row>;
|
|
12
|
+
close(): void;
|
|
13
|
+
private statement;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=Database.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Database.d.ts","sourceRoot":"","sources":["../../src/models/Database.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,aAAa,EAEnB,MAAM,aAAa,CAAA;AAEpB,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;AASvD,qBAAa,QAAQ;IAGC,OAAO,CAAC,QAAQ,CAAC,EAAE;IAFvC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAmC;IAE9D,OAAO;WAEO,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ;IAQnC,IAAI,CAAC,GAAG,EAAE,MAAM;IAIhB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE;IAazC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE;IAepC,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,aAAa,EAAE,GACP,QAAQ,CAAC,GAAG,CAAC;IAGzD,KAAK;IAIZ,OAAO,CAAC,SAAS;CAWlB"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { DatabaseSync, } from 'node:sqlite';
|
|
2
|
+
const PRAGMAS = `
|
|
3
|
+
PRAGMA locking_mode = EXCLUSIVE;
|
|
4
|
+
PRAGMA journal_mode = OFF;
|
|
5
|
+
PRAGMA synchronous = OFF;
|
|
6
|
+
PRAGMA temp_store = FILE;
|
|
7
|
+
`;
|
|
8
|
+
export class Database {
|
|
9
|
+
db;
|
|
10
|
+
statements = new Map();
|
|
11
|
+
constructor(db) {
|
|
12
|
+
this.db = db;
|
|
13
|
+
}
|
|
14
|
+
static open(file) {
|
|
15
|
+
const db = new DatabaseSync(file);
|
|
16
|
+
db.exec(PRAGMAS);
|
|
17
|
+
return new Database(db);
|
|
18
|
+
}
|
|
19
|
+
exec(sql) {
|
|
20
|
+
this.db.exec(sql);
|
|
21
|
+
}
|
|
22
|
+
insert(table, rows) {
|
|
23
|
+
const [first] = rows;
|
|
24
|
+
if (!first)
|
|
25
|
+
return;
|
|
26
|
+
const columns = Object.keys(first);
|
|
27
|
+
this.run(`INSERT INTO ${table} (${columns.join(', ')}) VALUES (${columns.map(column => `:${column}`).join(', ')})`, rows);
|
|
28
|
+
}
|
|
29
|
+
run(sql, rows) {
|
|
30
|
+
const statement = this.statement(sql);
|
|
31
|
+
this.db.exec('BEGIN');
|
|
32
|
+
try {
|
|
33
|
+
for (const row of rows)
|
|
34
|
+
statement.run(row);
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
this.db.exec('ROLLBACK');
|
|
38
|
+
throw error;
|
|
39
|
+
}
|
|
40
|
+
this.db.exec('COMMIT');
|
|
41
|
+
}
|
|
42
|
+
select(sql, ...params) {
|
|
43
|
+
return this.statement(sql).iterate(...params);
|
|
44
|
+
}
|
|
45
|
+
close() {
|
|
46
|
+
this.db.close();
|
|
47
|
+
}
|
|
48
|
+
statement(sql) {
|
|
49
|
+
const cached = this.statements.get(sql);
|
|
50
|
+
if (cached)
|
|
51
|
+
return cached;
|
|
52
|
+
const statement = this.db.prepare(sql);
|
|
53
|
+
this.statements.set(sql, statement);
|
|
54
|
+
return statement;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=Database.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Database.js","sourceRoot":"","sources":["../../src/models/Database.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,GAGb,MAAM,aAAa,CAAA;AAIpB,MAAM,OAAO,GAAG;;;;;CAKf,CAAA;AAED,MAAM,OAAO,QAAQ;IAGkB;IAFpB,UAAU,GAAG,IAAI,GAAG,EAAyB,CAAA;IAE9D,YAAqC,EAAgB;QAAhB,OAAE,GAAF,EAAE,CAAc;IAAG,CAAC;IAElD,MAAM,CAAC,IAAI,CAAC,IAAY;QAC7B,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,CAAA;QAEjC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QAEhB,OAAO,IAAI,QAAQ,CAAC,EAAE,CAAC,CAAA;IACzB,CAAC;IAEM,IAAI,CAAC,GAAW;QACrB,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACnB,CAAC;IAEM,MAAM,CAAC,KAAa,EAAE,IAAmB;QAC9C,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAA;QAEpB,IAAI,CAAC,KAAK;YAAE,OAAM;QAElB,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAElC,IAAI,CAAC,GAAG,CACN,eAAe,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EACzG,IAAI,CACL,CAAA;IACH,CAAC;IAEM,GAAG,CAAC,GAAW,EAAE,IAAmB;QACzC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;QAErC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QAErB,IAAI,CAAC;YACH,KAAK,MAAM,GAAG,IAAI,IAAI;gBAAE,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QAC5C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;YACxB,MAAM,KAAK,CAAA;QACb,CAAC;QAED,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;IACxB,CAAC;IAEM,MAAM,CAAM,GAAW,EAAE,GAAG,MAAuB;QACxD,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,MAAM,CAAkB,CAAA;IAChE,CAAC;IAEM,KAAK;QACV,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAA;IACjB,CAAC;IAEO,SAAS,CAAC,GAAW;QAC3B,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QAEvC,IAAI,MAAM;YAAE,OAAO,MAAM,CAAA;QAEzB,MAAM,SAAS,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QAEtC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,CAAC,CAAA;QAEnC,OAAO,SAAS,CAAA;IAClB,CAAC;CACF"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { OrderedRecord } from './BinarySource.js';
|
|
2
|
+
export type KeyGroup = {
|
|
3
|
+
key: string;
|
|
4
|
+
slice: string;
|
|
5
|
+
rows: Record<string, string>;
|
|
6
|
+
};
|
|
7
|
+
export type GroupJoints = {
|
|
8
|
+
main: string;
|
|
9
|
+
with: Record<string, string>;
|
|
10
|
+
};
|
|
11
|
+
export declare class OpenKeyGroup {
|
|
12
|
+
readonly key: string;
|
|
13
|
+
private readonly joints;
|
|
14
|
+
private readonly slice;
|
|
15
|
+
private readonly rows;
|
|
16
|
+
private size;
|
|
17
|
+
constructor(key: string, joints: GroupJoints);
|
|
18
|
+
accepts(record: OrderedRecord): boolean;
|
|
19
|
+
add(record: OrderedRecord): void;
|
|
20
|
+
build(): KeyGroup;
|
|
21
|
+
private sourceOf;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=OpenKeyGroup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OpenKeyGroup.d.ts","sourceRoot":"","sources":["../../src/models/OpenKeyGroup.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAGtD,MAAM,MAAM,QAAQ,GAAG;IACrB,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC7B,CAAA;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC7B,CAAA;AAED,qBAAa,YAAY;aAML,GAAG,EAAE,MAAM;IAC3B,OAAO,CAAC,QAAQ,CAAC,MAAM;IANzB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAe;IACrC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA8B;IACnD,OAAO,CAAC,IAAI,CAAI;gBAGE,GAAG,EAAE,MAAM,EACV,MAAM,EAAE,WAAW;IAG/B,OAAO,CAAC,MAAM,EAAE,aAAa;IAI7B,GAAG,CAAC,MAAM,EAAE,aAAa;IAezB,KAAK,IAAI,QAAQ;IAaxB,OAAO,CAAC,QAAQ;CASjB"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { MAX_SLICE_BYTES } from '../helpers/split-records.js';
|
|
2
|
+
export class OpenKeyGroup {
|
|
3
|
+
key;
|
|
4
|
+
joints;
|
|
5
|
+
slice = [];
|
|
6
|
+
rows = new Map();
|
|
7
|
+
size = 0;
|
|
8
|
+
constructor(key, joints) {
|
|
9
|
+
this.key = key;
|
|
10
|
+
this.joints = joints;
|
|
11
|
+
}
|
|
12
|
+
accepts(record) {
|
|
13
|
+
return record.key === this.key;
|
|
14
|
+
}
|
|
15
|
+
add(record) {
|
|
16
|
+
const { texts, joint } = this.sourceOf(record);
|
|
17
|
+
this.size += Buffer.byteLength(record.text);
|
|
18
|
+
if (texts.length > 0)
|
|
19
|
+
this.size += Buffer.byteLength(joint);
|
|
20
|
+
if (this.size > MAX_SLICE_BYTES)
|
|
21
|
+
throw new RangeError(`Split group of key ${this.key} is larger than ${String(MAX_SLICE_BYTES)} bytes (${String(this.size)} so far): check the groupBy key`);
|
|
22
|
+
texts.push(record.text);
|
|
23
|
+
}
|
|
24
|
+
build() {
|
|
25
|
+
return {
|
|
26
|
+
key: this.key,
|
|
27
|
+
slice: this.slice.join(this.joints.main),
|
|
28
|
+
rows: Object.fromEntries(Object.entries(this.joints.with).map(([name, joint]) => [
|
|
29
|
+
name,
|
|
30
|
+
this.rows.get(name)?.join(joint) ?? '',
|
|
31
|
+
])),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
sourceOf(record) {
|
|
35
|
+
if (record.isMain)
|
|
36
|
+
return { texts: this.slice, joint: this.joints.main };
|
|
37
|
+
const texts = this.rows.get(record.name) ?? [];
|
|
38
|
+
this.rows.set(record.name, texts);
|
|
39
|
+
return { texts, joint: this.joints.with[record.name] ?? '' };
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=OpenKeyGroup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OpenKeyGroup.js","sourceRoot":"","sources":["../../src/models/OpenKeyGroup.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAa7D,MAAM,OAAO,YAAY;IAML;IACC;IANF,KAAK,GAAa,EAAE,CAAA;IACpB,IAAI,GAAG,IAAI,GAAG,EAAoB,CAAA;IAC3C,IAAI,GAAG,CAAC,CAAA;IAEhB,YACkB,GAAW,EACV,MAAmB;QADpB,QAAG,GAAH,GAAG,CAAQ;QACV,WAAM,GAAN,MAAM,CAAa;IACnC,CAAC;IAEG,OAAO,CAAC,MAAqB;QAClC,OAAO,MAAM,CAAC,GAAG,KAAK,IAAI,CAAC,GAAG,CAAA;IAChC,CAAC;IAEM,GAAG,CAAC,MAAqB;QAC9B,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;QAE9C,IAAI,CAAC,IAAI,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QAE3C,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,IAAI,CAAC,IAAI,IAAI,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA;QAE3D,IAAI,IAAI,CAAC,IAAI,GAAG,eAAe;YAC7B,MAAM,IAAI,UAAU,CAClB,sBAAsB,IAAI,CAAC,GAAG,mBAAmB,MAAM,CAAC,eAAe,CAAC,WAAW,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,iCAAiC,CACtI,CAAA;QAEH,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACzB,CAAC;IAEM,KAAK;QACV,OAAO;YACL,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;YACxC,IAAI,EAAE,MAAM,CAAC,WAAW,CACtB,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC;gBACtD,IAAI;gBACJ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE;aACvC,CAAC,CACH;SACF,CAAA;IACH,CAAC;IAEO,QAAQ,CAAC,MAAqB;QACpC,IAAI,MAAM,CAAC,MAAM;YAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAA;QAExE,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAA;QAE9C,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;QAEjC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAA;IAC9D,CAAC;CACF"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { BinaryRecord, OrderedRecord } from './BinarySource.js';
|
|
2
|
+
export declare class SplitDatabaseWorker {
|
|
3
|
+
private readonly worker;
|
|
4
|
+
private readonly folder;
|
|
5
|
+
private readonly stopped;
|
|
6
|
+
private constructor();
|
|
7
|
+
static open(directory: string): Promise<SplitDatabaseWorker>;
|
|
8
|
+
recordsByKey(main: AsyncIterable<BinaryRecord>, withFiles: Record<string, AsyncIterable<BinaryRecord>>): AsyncGenerator<OrderedRecord>;
|
|
9
|
+
close(): Promise<void>;
|
|
10
|
+
private send;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=SplitDatabaseWorker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SplitDatabaseWorker.d.ts","sourceRoot":"","sources":["../../src/models/SplitDatabaseWorker.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAWpE,qBAAa,mBAAmB;IAE5B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAH1B,OAAO;WAMa,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAsB3D,YAAY,CACxB,IAAI,EAAE,aAAa,CAAC,YAAY,CAAC,EACjC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC,GACrD,cAAc,CAAC,aAAa,CAAC;IA6BnB,KAAK;IAMlB,OAAO,CAAC,IAAI;CAYb"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { once } from 'node:events';
|
|
2
|
+
import { mkdtemp, rm } from 'node:fs/promises';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { ReadableStream, TransformStream } from 'node:stream/web';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
import { Worker } from 'node:worker_threads';
|
|
7
|
+
import { inChunks } from '../helpers/in-chunks.js';
|
|
8
|
+
const WORKER = fileURLToPath(new URL('../../dist/workers/split-database.js', import.meta.url));
|
|
9
|
+
export class SplitDatabaseWorker {
|
|
10
|
+
worker;
|
|
11
|
+
folder;
|
|
12
|
+
stopped;
|
|
13
|
+
constructor(worker, folder, stopped) {
|
|
14
|
+
this.worker = worker;
|
|
15
|
+
this.folder = folder;
|
|
16
|
+
this.stopped = stopped;
|
|
17
|
+
}
|
|
18
|
+
static async open(directory) {
|
|
19
|
+
const folder = await mkdtemp(join(directory, 't4h-split-'));
|
|
20
|
+
const workerData = {
|
|
21
|
+
file: join(folder, 'split.db'),
|
|
22
|
+
};
|
|
23
|
+
const worker = new Worker(WORKER, { workerData });
|
|
24
|
+
const stop = new AbortController();
|
|
25
|
+
worker.on('error', error => {
|
|
26
|
+
stop.abort(error);
|
|
27
|
+
});
|
|
28
|
+
worker.on('exit', code => {
|
|
29
|
+
stop.abort(new Error(`The split database worker stopped with code ${String(code)}`));
|
|
30
|
+
});
|
|
31
|
+
return new SplitDatabaseWorker(worker, folder, stop.signal);
|
|
32
|
+
}
|
|
33
|
+
async *recordsByKey(main, withFiles) {
|
|
34
|
+
const mainInput = this.send(main);
|
|
35
|
+
const withInputs = Object.entries(withFiles).map(([name, records]) => ({
|
|
36
|
+
name,
|
|
37
|
+
...this.send(records),
|
|
38
|
+
}));
|
|
39
|
+
const inputs = [mainInput, ...withInputs];
|
|
40
|
+
const load = {
|
|
41
|
+
main: mainInput.readable,
|
|
42
|
+
with: withInputs.map(({ name, readable }) => [name, readable]),
|
|
43
|
+
};
|
|
44
|
+
const reply = once(this.worker, 'message', { signal: this.stopped });
|
|
45
|
+
this.worker.postMessage(load, inputs.map(({ readable }) => readable));
|
|
46
|
+
await Promise.all([...inputs.map(({ sent }) => sent), reply]);
|
|
47
|
+
const [ordered] = (await reply);
|
|
48
|
+
const chunks = ordered.pipeThrough(new TransformStream(), { signal: this.stopped });
|
|
49
|
+
for await (const records of chunks)
|
|
50
|
+
yield* records;
|
|
51
|
+
}
|
|
52
|
+
async close() {
|
|
53
|
+
await this.worker.terminate();
|
|
54
|
+
await rm(this.folder, { recursive: true, force: true });
|
|
55
|
+
}
|
|
56
|
+
send(records) {
|
|
57
|
+
const { readable, writable } = new TransformStream();
|
|
58
|
+
const sent = ReadableStream.from(inChunks(records)).pipeTo(writable, {
|
|
59
|
+
preventAbort: true,
|
|
60
|
+
signal: this.stopped,
|
|
61
|
+
});
|
|
62
|
+
return { readable, sent };
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=SplitDatabaseWorker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SplitDatabaseWorker.js","sourceRoot":"","sources":["../../src/models/SplitDatabaseWorker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ReadableStream } from 'node:stream/web';
|
|
2
|
+
import type { BinaryRecord } from '../models/BinarySource.js';
|
|
3
|
+
export type SplitDatabaseWorkerData = {
|
|
4
|
+
file: string;
|
|
5
|
+
};
|
|
6
|
+
export type SplitDatabaseLoad = {
|
|
7
|
+
main: ReadableStream<BinaryRecord[]>;
|
|
8
|
+
with: [name: string, records: ReadableStream<BinaryRecord[]>][];
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=split-database.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"split-database.d.ts","sourceRoot":"","sources":["../../src/workers/split-database.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAIhD,OAAO,KAAK,EAAE,YAAY,EAAiB,MAAM,2BAA2B,CAAA;AAG5E,MAAM,MAAM,uBAAuB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAEtD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,cAAc,CAAC,YAAY,EAAE,CAAC,CAAA;IACpC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,CAAC,YAAY,EAAE,CAAC,CAAC,EAAE,CAAA;CAChE,CAAA"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { ReadableStream } from 'node:stream/web';
|
|
2
|
+
import { parentPort, workerData } from 'node:worker_threads';
|
|
3
|
+
import { inChunks } from '../helpers/in-chunks.js';
|
|
4
|
+
import { Database } from '../models/Database.js';
|
|
5
|
+
const SQL = {
|
|
6
|
+
schema: `
|
|
7
|
+
CREATE TABLE main_rows (key TEXT NOT NULL, text TEXT NOT NULL);
|
|
8
|
+
CREATE TABLE with_rows (key TEXT NOT NULL, name TEXT NOT NULL, text TEXT NOT NULL);
|
|
9
|
+
`,
|
|
10
|
+
indexMain: 'CREATE INDEX main_key ON main_rows (key)',
|
|
11
|
+
indexWith: 'CREATE INDEX with_key ON with_rows (key, name)',
|
|
12
|
+
insertWithMainKey: 'INSERT INTO with_rows (key, name, text) SELECT :key, :name, :text WHERE EXISTS (SELECT 1 FROM main_rows WHERE key = :key)',
|
|
13
|
+
recordsByKey: `
|
|
14
|
+
SELECT key, 1 AS is_main, NULL AS name, rowid AS seq, text FROM main_rows
|
|
15
|
+
UNION ALL
|
|
16
|
+
SELECT key, 0 AS is_main, name, rowid AS seq, text FROM with_rows
|
|
17
|
+
ORDER BY key, name, seq
|
|
18
|
+
`,
|
|
19
|
+
};
|
|
20
|
+
const { file } = workerData;
|
|
21
|
+
const database = Database.open(file);
|
|
22
|
+
database.exec(SQL.schema);
|
|
23
|
+
function* recordsByKey() {
|
|
24
|
+
for (const row of database.select(SQL.recordsByKey))
|
|
25
|
+
yield row.is_main === 1
|
|
26
|
+
? { key: row.key, text: row.text, isMain: true }
|
|
27
|
+
: { key: row.key, text: row.text, isMain: false, name: row.name };
|
|
28
|
+
}
|
|
29
|
+
async function load({ main, with: sources }) {
|
|
30
|
+
for await (const records of main)
|
|
31
|
+
database.insert('main_rows', records);
|
|
32
|
+
database.exec(SQL.indexMain);
|
|
33
|
+
for (const [name, chunks] of sources)
|
|
34
|
+
for await (const records of chunks)
|
|
35
|
+
database.run(SQL.insertWithMainKey, records.map(({ key, text }) => ({ key, name, text })));
|
|
36
|
+
database.exec(SQL.indexWith);
|
|
37
|
+
const ordered = ReadableStream.from(inChunks(recordsByKey()));
|
|
38
|
+
parentPort?.postMessage(ordered, [ordered]);
|
|
39
|
+
}
|
|
40
|
+
parentPort?.on('message', (request) => {
|
|
41
|
+
void load(request);
|
|
42
|
+
});
|
|
43
|
+
//# sourceMappingURL=split-database.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"split-database.js","sourceRoot":"","sources":["../../src/workers/split-database.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAE5D,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAElD,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAA;AAchD,MAAM,GAAG,GAAG;IACV,MAAM,EAAE;;;GAGP;IACD,SAAS,EAAE,0CAA0C;IACrD,SAAS,EAAE,gDAAgD;IAC3D,iBAAiB,EACf,2HAA2H;IAC7H,YAAY,EAAE;;;;;GAKb;CACF,CAAA;AAED,MAAM,EAAE,IAAI,EAAE,GAAG,UAAqC,CAAA;AACtD,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAEpC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;AAEzB,QAAQ,CAAC,CAAC,YAAY;IACpB,KAAK,MAAM,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAa,GAAG,CAAC,YAAY,CAAC;QAC7D,MAAM,GAAG,CAAC,OAAO,KAAK,CAAC;YACrB,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE;YAChD,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAA;AACvE,CAAC;AAED,KAAK,UAAU,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAqB;IAC5D,IAAI,KAAK,EAAE,MAAM,OAAO,IAAI,IAAI;QAAE,QAAQ,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA;IAEvE,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;IAE5B,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,OAAO;QAClC,IAAI,KAAK,EAAE,MAAM,OAAO,IAAI,MAAM;YAChC,QAAQ,CAAC,GAAG,CACV,GAAG,CAAC,iBAAiB,EACrB,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CACtD,CAAA;IAEL,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;IAE5B,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE,CAAC,CAAC,CAAA;IAE7D,UAAU,EAAE,WAAW,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,CAAC,CAAA;AAC7C,CAAC;AAED,UAAU,EAAE,EAAE,CAAC,SAAS,EAAE,CAAC,OAA0B,EAAE,EAAE;IACvD,KAAK,IAAI,CAAC,OAAO,CAAC,CAAA;AACpB,CAAC,CAAC,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@t4h.framework/fs",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"description": "File system module for the T4H Framework",
|
|
5
5
|
"homepage": "https://github.com/tech4humans-brasil/framework/tree/main/packages/fs",
|
|
6
6
|
"bugs": "https://github.com/tech4humans-brasil/framework/issues",
|
|
@@ -26,13 +26,14 @@
|
|
|
26
26
|
"scripts": {
|
|
27
27
|
"build": "tsc --project tsconfig.build.json",
|
|
28
28
|
"check-types": "tsc --noEmit",
|
|
29
|
-
"
|
|
29
|
+
"check-package": "publint --strict && attw --pack . --profile esm-only",
|
|
30
|
+
"lint": "eslint . --max-warnings 0",
|
|
30
31
|
"prepublishOnly": "yarn build",
|
|
31
32
|
"test": "vitest run",
|
|
32
33
|
"test:watch": "vitest"
|
|
33
34
|
},
|
|
34
35
|
"devDependencies": {
|
|
35
|
-
"@t4h.framework/core": "^0.
|
|
36
|
+
"@t4h.framework/core": "^0.21.0",
|
|
36
37
|
"typescript": "^5.9.3",
|
|
37
38
|
"vitest": "^4.0.18"
|
|
38
39
|
},
|
|
@@ -41,7 +42,7 @@
|
|
|
41
42
|
},
|
|
42
43
|
"packageManager": "yarn@4.12.0",
|
|
43
44
|
"engines": {
|
|
44
|
-
"node": ">=22"
|
|
45
|
+
"node": ">=22.13"
|
|
45
46
|
},
|
|
46
47
|
"dependencies": {
|
|
47
48
|
"sift": "^17.1.3"
|