@gadgetinc/dateilager 0.5.3 → 0.5.4

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.
@@ -43,6 +43,12 @@ export interface DateiLagerBinaryClientOptions {
43
43
  * @default 0 No timeout.
44
44
  */
45
45
  rebuild?: number;
46
+ /**
47
+ * The default number of milliseconds to wait before terminating the gc command.
48
+ *
49
+ * @default 0 No timeout.
50
+ */
51
+ gc?: number;
46
52
  };
47
53
  /**
48
54
  * Whether the dateilager binary client should enable tracing.
@@ -83,6 +89,15 @@ export interface RebuildResult {
83
89
  */
84
90
  patternMatch: boolean;
85
91
  }
92
+ /**
93
+ * The Result from calling the Dateilager Garbage Compiler
94
+ */
95
+ export interface GCResult {
96
+ /**
97
+ * The number of records garbage collected
98
+ */
99
+ count: bigint;
100
+ }
86
101
  /**
87
102
  * A version of the DateiLager client that uses the compiled binary client instead of the Javascript one.
88
103
  *
@@ -126,4 +141,34 @@ export declare class DateiLagerBinaryClient {
126
141
  filePattern?: string;
127
142
  filePatternIff?: boolean;
128
143
  }): Promise<RebuildResult>;
144
+ /**
145
+ * @param sample sample size of cleanup
146
+ * @param keep The amount of records to keep
147
+ * @param from Where to start cleanup
148
+ * @param options dict options passed
149
+ * @param options.timeout timeout limit for the request
150
+ */
151
+ gcRandomProjects(sample: number, keep: bigint, from?: bigint, options?: {
152
+ timeout?: number;
153
+ }): Promise<GCResult>;
154
+ /**
155
+ *
156
+ * @param project The selected project to cleanup
157
+ * @param keep The amount of records to keep
158
+ * @param from Where to start cleanup
159
+ * @param options dict options passed
160
+ * @param options.timeout timeout limit for the request
161
+ */
162
+ gcProject(project: bigint, keep: bigint, from?: bigint, options?: {
163
+ timeout?: number;
164
+ }): Promise<GCResult>;
165
+ /**
166
+ *
167
+ * @param sample sample size of cleanup
168
+ * @param options dict options passed
169
+ * @param options.timeout timeout limit for the request
170
+ */
171
+ gcContents(sample: number, options?: {
172
+ timeout?: number;
173
+ }): Promise<GCResult>;
129
174
  }
@@ -60,7 +60,8 @@ class DateiLagerBinaryClient {
60
60
  "dl.directory": directory,
61
61
  },
62
62
  }, async () => {
63
- const result = await this._call("update", project, directory, ["--dir", directory], options);
63
+ const args = ["--dir", String(directory), "--project", String(project)];
64
+ const result = await this._call("update", args, directory, options);
64
65
  if (result.stdout == "-1") {
65
66
  return null;
66
67
  }
@@ -106,14 +107,82 @@ class DateiLagerBinaryClient {
106
107
  args.push(`--iff=true`);
107
108
  }
108
109
  }
109
- const result = await this._call("rebuild", project, directory, args, options);
110
+ args.push("--project", String(project), "--dir", directory);
111
+ const result = await this._call("rebuild", args, directory, options);
110
112
  const parsed = JSON.parse(result.stdout);
111
113
  return { version: BigInt(parsed.version), count: parsed.count, patternMatch: parsed.patternMatch };
112
114
  });
113
115
  }
116
+ /**
117
+ * @param sample sample size of cleanup
118
+ * @param keep The amount of records to keep
119
+ * @param from Where to start cleanup
120
+ * @param options dict options passed
121
+ * @param options.timeout timeout limit for the request
122
+ */
123
+ async gcRandomProjects(sample, keep, from, options) {
124
+ return await (0, telemetry_1.trace)("dateilager-binary-client.gc", {
125
+ attributes: {
126
+ "db.mode": "random-projects",
127
+ "dl.keep": String(keep),
128
+ "dl.from": String(from),
129
+ "dl.sample": String(sample),
130
+ },
131
+ }, async () => {
132
+ const args = ["--mode", "random-projects", "--keep", String(keep), "--sample", String(sample)];
133
+ if (from)
134
+ args.push("--from", String(from));
135
+ const result = await this._call("gc", args, undefined, options);
136
+ const parsed = JSON.parse(result.stdout);
137
+ return { count: parsed.count };
138
+ });
139
+ }
140
+ /**
141
+ *
142
+ * @param project The selected project to cleanup
143
+ * @param keep The amount of records to keep
144
+ * @param from Where to start cleanup
145
+ * @param options dict options passed
146
+ * @param options.timeout timeout limit for the request
147
+ */
148
+ async gcProject(project, keep, from, options) {
149
+ return await (0, telemetry_1.trace)("dateilager-binary-client.gc", {
150
+ attributes: {
151
+ "db.mode": "mode",
152
+ "dl.keep": String(keep),
153
+ "dl.from": String(from),
154
+ },
155
+ }, async () => {
156
+ const args = ["--mode", "project", "--keep", String(keep), "--project", String(project)];
157
+ if (from)
158
+ args.push("--from", String(from));
159
+ const result = await this._call("gc", args, undefined, options);
160
+ const parsed = JSON.parse(result.stdout);
161
+ return { count: parsed.count };
162
+ });
163
+ }
164
+ /**
165
+ *
166
+ * @param sample sample size of cleanup
167
+ * @param options dict options passed
168
+ * @param options.timeout timeout limit for the request
169
+ */
170
+ async gcContents(sample, options) {
171
+ return await (0, telemetry_1.trace)("dateilager-binary-client.gc", {
172
+ attributes: {
173
+ "db.mode": "contents",
174
+ "dl.sample": String(sample),
175
+ },
176
+ }, async () => {
177
+ const args = ["--mode", "contents", "--sample", String(sample)];
178
+ const result = await this._call("gc", args, undefined, options);
179
+ const parsed = JSON.parse(result.stdout);
180
+ return { count: parsed.count };
181
+ });
182
+ }
114
183
  /** @internal */
115
- async _call(method, project, cwd, args, options) {
116
- const baseArgs = [method, "--project", String(project), "--server", this._options.server, "--log-encoding", "json"];
184
+ async _call(method, args, cwd, options) {
185
+ const baseArgs = [method, "--server", this._options.server, "--log-encoding", "json"];
117
186
  if (this._options.logger) {
118
187
  baseArgs.push("--log-level", this._options.logger.level);
119
188
  }
@@ -1 +1 @@
1
- {"version":3,"file":"binary-client.js","sourceRoot":"","sources":["../../src/binary-client.ts"],"names":[],"mappings":";;;;;;AAAA,4CAA0D;AAE1D,kDAA0B;AAC1B,2DAA6B;AAC7B,wDAAgC;AAChC,oDAA6C;AAqG7C;;;;GAIG;AACH,MAAa,sBAAsB;IAIjC;;OAEG;IACH,YAAmB,OAAsC;QANzD,gBAAgB;QAChB;;;;;WAA0B;QAMxB,IAAI,CAAC,QAAQ,GAAG;YACd,MAAM,EAAE,OAAO,OAAO,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE;YAC7G,KAAK,EAAE,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,KAAe,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK;YACzG,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,mBAAmB;YAC/C,OAAO,EACL,OAAO,OAAO,CAAC,OAAO,KAAK,QAAQ;gBACjC,CAAC,CAAC;oBACE,MAAM,EAAE,OAAO,CAAC,OAAO;oBACvB,OAAO,EAAE,OAAO,CAAC,OAAO;iBACzB;gBACH,CAAC,CAAC;oBACE,MAAM,EAAE,CAAC;oBACT,OAAO,EAAE,CAAC;oBACV,GAAG,OAAO,CAAC,OAAO;iBACnB;YACP,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,KAAK;YACjC,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC;IACJ,CAAC;IAED;;;;;;;;OAQG;IACI,KAAK,CAAC,MAAM,CAAC,OAAe,EAAE,SAAiB,EAAE,OAA8B;QACpF,OAAO,MAAM,IAAA,iBAAK,EAChB,iCAAiC,EACjC;YACE,UAAU,EAAE;gBACV,YAAY,EAAE,MAAM,CAAC,OAAO,CAAC;gBAC7B,cAAc,EAAE,SAAS;aAC1B;SACF,EACD,KAAK,IAAI,EAAE;YACT,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,OAAO,CAAC,CAAC;YAE7F,IAAI,MAAM,CAAC,MAAM,IAAI,IAAI,EAAE;gBACzB,OAAO,IAAI,CAAC;aACb;YAED,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC/B,CAAC,CACF,CAAC;IACJ,CAAC;IAED;;;;;;;;;;;;;OAaG;IACI,KAAK,CAAC,OAAO,CAClB,OAAe,EACf,EAAiB,EACjB,SAAiB,EACjB,OAAuH;QAEvH,OAAO,MAAM,IAAA,iBAAK,EAChB,kCAAkC,EAClC;YACE,UAAU,EAAE;gBACV,YAAY,EAAE,MAAM,CAAC,OAAO,CAAC;gBAC7B,OAAO,EAAE,MAAM,CAAC,EAAE,CAAC;gBACnB,cAAc,EAAE,SAAS;aAC1B;SACF,EACD,KAAK,IAAI,EAAE;YACT,MAAM,kBAAE,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAE/C,MAAM,IAAI,GAAG,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;YAClC,IAAI,EAAE,EAAE;gBACN,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;aAC/B;YAED,IAAI,OAAO,EAAE,OAAO,EAAE;gBACpB,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;aACnD;YAED,IAAI,OAAO,EAAE,SAAS,KAAK,KAAK,EAAE;gBAChC,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;aAChC;YAED,IAAI,OAAO,EAAE,WAAW,EAAE;gBACxB,IAAI,CAAC,IAAI,CAAC,iBAAiB,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;gBAElD,IAAI,OAAO,CAAC,cAAc,EAAE;oBAC1B,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;iBACzB;aACF;YAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;YAC9E,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAA8D,CAAC;YACtG,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,YAAY,EAAE,MAAM,CAAC,YAAY,EAAE,CAAC;QACrG,CAAC,CACF,CAAC;IACJ,CAAC;IAED,gBAAgB;IACR,KAAK,CAAC,KAAK,CACjB,MAA4B,EAC5B,OAAe,EACf,GAAW,EACX,IAAc,EACd,OAA8B;QAE9B,MAAM,QAAQ,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,EAAE,MAAM,CAAC,CAAC;QAEpH,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE;YACxB,QAAQ,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;SAC1D;QAED,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE;YACzB,MAAM,OAAO,GAAG,EAAE,CAAC;YACnB,iBAAW,CAAC,MAAM,CAAC,aAAO,CAAC,MAAM,EAAE,EAAE,OAAO,CAAC,CAAC;YAC9C,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YAE5C,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,gBAAgB,EAAE,WAAW,CAAC,CAAC;SAC3D;QAED,MAAM,UAAU,GAAG,IAAA,eAAK,EAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;YACrE,GAAG;YACH,OAAO,EAAE,OAAO,EAAE,OAAO,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC;YAC1D,GAAG,EAAE,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE;SAC/C,CAAC,CAAC;QAEH,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,IAAI,UAAU,CAAC,MAAM,EAAE;YAC7C,kBAAQ,CAAC,eAAe,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;gBAC9D,IAAI;oBACF,oDAAoD;oBACpD,6DAA6D;oBAC7D,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAKpD,CAAC;oBAEF,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;iBAC/C;gBAAC,OAAO,KAAK,EAAE;oBACd,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,oBAAoB,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;iBAC1E;YACH,CAAC,CAAC,CAAC;SACJ;QAED,OAAO,UAAU,CAAC;IACpB,CAAC;CACF;AAvKD,wDAuKC","sourcesContent":["import { context, propagation } from \"@opentelemetry/api\";\nimport type { ExecaReturnValue } from \"execa\";\nimport execa from \"execa\";\nimport fs from \"fs/promises\";\nimport readline from \"readline\";\nimport { trace } from \"./internal/telemetry\";\n\n/**\n * Options for {@link DateiLagerBinaryClient}.\n */\nexport interface DateiLagerBinaryClientOptions {\n /**\n * The address of the dateilager server.\n */\n server:\n | string\n | {\n /**\n * The host of the dateilager server.\n */\n host: string;\n\n /**\n * The port of the dateilager server.\n */\n port: number;\n };\n\n /**\n * The token that will be sent as authorization metadata to the dateilager server.\n */\n token: string | (() => Promise<string>);\n\n /**\n * The path to the dateilager-client executable.\n *\n * @default \"dateilager-client\"\n */\n command?: string;\n\n /**\n * The default number of milliseconds to wait before terminating any command.\n *\n * @default 0 No timeout.\n */\n timeout?:\n | number\n | {\n /**\n * The default number of milliseconds to wait before terminating the update command.\n *\n * @default 0 No timeout.\n */\n update?: number;\n\n /**\n * The default number of milliseconds to wait before terminating the rebuild command.\n *\n * @default 0 No timeout.\n */\n rebuild?: number;\n };\n\n /**\n * Whether the dateilager binary client should enable tracing.\n *\n * @default false\n */\n tracing?: boolean;\n\n /**\n * Logging configuration.\n */\n logger?: {\n /**\n * The log level to pass to the dateilager binary client.\n */\n level: \"debug\" | \"info\" | \"warn\" | \"error\";\n\n /**\n * The function that will be called when the dateilager binary client logs something.\n */\n log: (level: \"debug\" | \"info\" | \"warn\" | \"error\", msg: string, fields: Record<string, unknown>) => void;\n };\n}\n\n/**\n * The version of the filesystem after the call to rebuild.\n *\n * If a file pattern was included then patternDetected can be used to know if that filepattern was seen while rebuilding.\n */\nexport interface RebuildResult {\n /**\n * Filesystem version.\n */\n version: bigint;\n /**\n * Files updated by the rebuild operation.\n */\n count: number;\n /**\n * Wether or not the file pattern was detected.\n */\n patternMatch: boolean;\n}\n\n/**\n * A version of the DateiLager client that uses the compiled binary client instead of the Javascript one.\n *\n * Useful for working directly with a real filesystem instead of in memory objects.\n */\nexport class DateiLagerBinaryClient {\n /** @internal */\n private readonly _options;\n\n /**\n * @param options An object with {@link DateiLagerBinaryClientOptions options}.\n */\n public constructor(options: DateiLagerBinaryClientOptions) {\n this._options = {\n server: typeof options.server === \"string\" ? options.server : `${options.server.host}:${options.server.port}`,\n token: typeof options.token === \"string\" ? () => Promise.resolve(options.token as string) : options.token,\n command: options.command ?? \"dateilager-client\",\n timeout:\n typeof options.timeout === \"number\"\n ? {\n update: options.timeout,\n rebuild: options.timeout,\n }\n : {\n update: 0,\n rebuild: 0,\n ...options.timeout,\n },\n tracing: options.tracing ?? false,\n logger: options.logger,\n };\n }\n\n /**\n * Update objects in a project based on the differences in a local directory.\n *\n * @param project The id of the project.\n * @param directory The path of the directory to send updates from.\n * @param options Object of options.\n * @param options.timeout Number of milliseconds to wait before terminating the process.\n * @returns The latest project version or `null` if something went wrong.\n */\n public async update(project: bigint, directory: string, options?: { timeout?: number }): Promise<bigint | null> {\n return await trace(\n \"dateilager-binary-client.update\",\n {\n attributes: {\n \"dl.project\": String(project),\n \"dl.directory\": directory,\n },\n },\n async () => {\n const result = await this._call(\"update\", project, directory, [\"--dir\", directory], options);\n\n if (result.stdout == \"-1\") {\n return null;\n }\n\n return BigInt(result.stdout);\n }\n );\n }\n\n /**\n * Rebuild the local filesystem.\n *\n * @param project The id of the project.\n * @param to The version of the project to rebuild the filesystem to.\n * @param directory The path of the directory to rebuild the filesystem at.\n * @param options Object of options.\n * @param options.timeout Number of milliseconds to wait before terminating the process.\n * @param options.ignores The paths to ignore when rebuilding the FS.\n * @param options.summarize Should produce the summary file after rebuilding.\n * @param options.filePattern A glob file pattern which drives the patternDetected output boolean\n * @param options.filePatternIff Should the file pattern detection trigger if and only if those files have changed\n * @returns The latest project version or `null` if something went wrong.\n */\n public async rebuild(\n project: bigint,\n to: bigint | null,\n directory: string,\n options?: { timeout?: number; ignores?: string[]; summarize?: boolean; filePattern?: string; filePatternIff?: boolean }\n ): Promise<RebuildResult> {\n return await trace(\n \"dateilager-binary-client.rebuild\",\n {\n attributes: {\n \"dl.project\": String(project),\n \"dl.to\": String(to),\n \"dl.directory\": directory,\n },\n },\n async () => {\n await fs.mkdir(directory, { recursive: true });\n\n const args = [\"--dir\", directory];\n if (to) {\n args.push(\"--to\", String(to));\n }\n\n if (options?.ignores) {\n args.push(\"--ignores\", options.ignores.join(\",\"));\n }\n\n if (options?.summarize === false) {\n args.push(\"--summarize=false\");\n }\n\n if (options?.filePattern) {\n args.push(`--filepattern=${options.filePattern}`);\n\n if (options.filePatternIff) {\n args.push(`--iff=true`);\n }\n }\n\n const result = await this._call(\"rebuild\", project, directory, args, options);\n const parsed = JSON.parse(result.stdout) as { version: number; count: number; patternMatch: boolean };\n return { version: BigInt(parsed.version), count: parsed.count, patternMatch: parsed.patternMatch };\n }\n );\n }\n\n /** @internal */\n private async _call(\n method: \"update\" | \"rebuild\",\n project: bigint,\n cwd: string,\n args: string[],\n options?: { timeout?: number }\n ): Promise<ExecaReturnValue> {\n const baseArgs = [method, \"--project\", String(project), \"--server\", this._options.server, \"--log-encoding\", \"json\"];\n\n if (this._options.logger) {\n baseArgs.push(\"--log-level\", this._options.logger.level);\n }\n\n if (this._options.tracing) {\n const carrier = {};\n propagation.inject(context.active(), carrier);\n const otelContext = JSON.stringify(carrier);\n\n baseArgs.push(\"--tracing\", \"--otel-context\", otelContext);\n }\n\n const subprocess = execa(this._options.command, baseArgs.concat(args), {\n cwd,\n timeout: options?.timeout ?? this._options.timeout[method],\n env: { DL_TOKEN: await this._options.token() },\n });\n\n if (this._options.logger && subprocess.stderr) {\n readline.createInterface(subprocess.stderr).on(\"line\", (line) => {\n try {\n // we purposefully extract and ignore the `ts` field\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { level, msg, ts, ...fields } = JSON.parse(line) as {\n [key: string]: unknown;\n level: \"debug\" | \"info\" | \"warn\" | \"error\";\n msg: string;\n ts: string | number;\n };\n\n this._options.logger?.log(level, msg, fields);\n } catch (error) {\n this._options.logger?.log(\"warn\", \"failed to log line\", { error, line });\n }\n });\n }\n\n return subprocess;\n }\n}\n"]}
1
+ {"version":3,"file":"binary-client.js","sourceRoot":"","sources":["../../src/binary-client.ts"],"names":[],"mappings":"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","sourcesContent":["import { context, propagation } from \"@opentelemetry/api\";\nimport type { ExecaReturnValue } from \"execa\";\nimport execa from \"execa\";\nimport fs from \"fs/promises\";\nimport readline from \"readline\";\nimport { trace } from \"./internal/telemetry\";\n\n/**\n * Options for {@link DateiLagerBinaryClient}.\n */\nexport interface DateiLagerBinaryClientOptions {\n /**\n * The address of the dateilager server.\n */\n server:\n | string\n | {\n /**\n * The host of the dateilager server.\n */\n host: string;\n\n /**\n * The port of the dateilager server.\n */\n port: number;\n };\n\n /**\n * The token that will be sent as authorization metadata to the dateilager server.\n */\n token: string | (() => Promise<string>);\n\n /**\n * The path to the dateilager-client executable.\n *\n * @default \"dateilager-client\"\n */\n command?: string;\n\n /**\n * The default number of milliseconds to wait before terminating any command.\n *\n * @default 0 No timeout.\n */\n timeout?:\n | number\n | {\n /**\n * The default number of milliseconds to wait before terminating the update command.\n *\n * @default 0 No timeout.\n */\n update?: number;\n\n /**\n * The default number of milliseconds to wait before terminating the rebuild command.\n *\n * @default 0 No timeout.\n */\n rebuild?: number;\n\n /**\n * The default number of milliseconds to wait before terminating the gc command.\n *\n * @default 0 No timeout.\n */\n gc?: number;\n };\n\n /**\n * Whether the dateilager binary client should enable tracing.\n *\n * @default false\n */\n tracing?: boolean;\n\n /**\n * Logging configuration.\n */\n logger?: {\n /**\n * The log level to pass to the dateilager binary client.\n */\n level: \"debug\" | \"info\" | \"warn\" | \"error\";\n\n /**\n * The function that will be called when the dateilager binary client logs something.\n */\n log: (level: \"debug\" | \"info\" | \"warn\" | \"error\", msg: string, fields: Record<string, unknown>) => void;\n };\n}\n\n/**\n * The version of the filesystem after the call to rebuild.\n *\n * If a file pattern was included then patternDetected can be used to know if that filepattern was seen while rebuilding.\n */\nexport interface RebuildResult {\n /**\n * Filesystem version.\n */\n version: bigint;\n /**\n * Files updated by the rebuild operation.\n */\n count: number;\n /**\n * Wether or not the file pattern was detected.\n */\n patternMatch: boolean;\n}\n\n/**\n * The Result from calling the Dateilager Garbage Compiler\n */\nexport interface GCResult {\n /**\n * The number of records garbage collected\n */\n count: bigint;\n}\n\n/**\n * A version of the DateiLager client that uses the compiled binary client instead of the Javascript one.\n *\n * Useful for working directly with a real filesystem instead of in memory objects.\n */\nexport class DateiLagerBinaryClient {\n /** @internal */\n private readonly _options;\n\n /**\n * @param options An object with {@link DateiLagerBinaryClientOptions options}.\n */\n public constructor(options: DateiLagerBinaryClientOptions) {\n this._options = {\n server: typeof options.server === \"string\" ? options.server : `${options.server.host}:${options.server.port}`,\n token: typeof options.token === \"string\" ? () => Promise.resolve(options.token as string) : options.token,\n command: options.command ?? \"dateilager-client\",\n timeout:\n typeof options.timeout === \"number\"\n ? {\n update: options.timeout,\n rebuild: options.timeout,\n }\n : {\n update: 0,\n rebuild: 0,\n ...options.timeout,\n },\n tracing: options.tracing ?? false,\n logger: options.logger,\n };\n }\n\n /**\n * Update objects in a project based on the differences in a local directory.\n *\n * @param project The id of the project.\n * @param directory The path of the directory to send updates from.\n * @param options Object of options.\n * @param options.timeout Number of milliseconds to wait before terminating the process.\n * @returns The latest project version or `null` if something went wrong.\n */\n public async update(project: bigint, directory: string, options?: { timeout?: number }): Promise<bigint | null> {\n return await trace(\n \"dateilager-binary-client.update\",\n {\n attributes: {\n \"dl.project\": String(project),\n \"dl.directory\": directory,\n },\n },\n async () => {\n const args = [\"--dir\", String(directory), \"--project\", String(project)];\n const result = await this._call(\"update\", args, directory, options);\n\n if (result.stdout == \"-1\") {\n return null;\n }\n\n return BigInt(result.stdout);\n }\n );\n }\n\n /**\n * Rebuild the local filesystem.\n *\n * @param project The id of the project.\n * @param to The version of the project to rebuild the filesystem to.\n * @param directory The path of the directory to rebuild the filesystem at.\n * @param options Object of options.\n * @param options.timeout Number of milliseconds to wait before terminating the process.\n * @param options.ignores The paths to ignore when rebuilding the FS.\n * @param options.summarize Should produce the summary file after rebuilding.\n * @param options.filePattern A glob file pattern which drives the patternDetected output boolean\n * @param options.filePatternIff Should the file pattern detection trigger if and only if those files have changed\n * @returns The latest project version or `null` if something went wrong.\n */\n public async rebuild(\n project: bigint,\n to: bigint | null,\n directory: string,\n options?: { timeout?: number; ignores?: string[]; summarize?: boolean; filePattern?: string; filePatternIff?: boolean }\n ): Promise<RebuildResult> {\n return await trace(\n \"dateilager-binary-client.rebuild\",\n {\n attributes: {\n \"dl.project\": String(project),\n \"dl.to\": String(to),\n \"dl.directory\": directory,\n },\n },\n async () => {\n await fs.mkdir(directory, { recursive: true });\n\n const args = [\"--dir\", directory];\n if (to) {\n args.push(\"--to\", String(to));\n }\n\n if (options?.ignores) {\n args.push(\"--ignores\", options.ignores.join(\",\"));\n }\n\n if (options?.summarize === false) {\n args.push(\"--summarize=false\");\n }\n\n if (options?.filePattern) {\n args.push(`--filepattern=${options.filePattern}`);\n\n if (options.filePatternIff) {\n args.push(`--iff=true`);\n }\n }\n\n args.push(\"--project\", String(project), \"--dir\", directory);\n const result = await this._call(\"rebuild\", args, directory, options);\n const parsed = JSON.parse(result.stdout) as { version: number; count: number; patternMatch: boolean };\n return { version: BigInt(parsed.version), count: parsed.count, patternMatch: parsed.patternMatch };\n }\n );\n }\n\n /**\n * @param sample sample size of cleanup\n * @param keep The amount of records to keep\n * @param from Where to start cleanup\n * @param options dict options passed\n * @param options.timeout timeout limit for the request\n */\n public async gcRandomProjects(sample: number, keep: bigint, from?: bigint, options?: { timeout?: number }): Promise<GCResult> {\n return await trace(\n \"dateilager-binary-client.gc\",\n {\n attributes: {\n \"db.mode\": \"random-projects\",\n \"dl.keep\": String(keep),\n \"dl.from\": String(from),\n \"dl.sample\": String(sample),\n },\n },\n async () => {\n const args = [\"--mode\", \"random-projects\", \"--keep\", String(keep), \"--sample\", String(sample)];\n\n if (from) args.push(\"--from\", String(from));\n\n const result = await this._call(\"gc\", args, undefined, options);\n const parsed = JSON.parse(result.stdout) as { count: bigint };\n return { count: parsed.count };\n }\n );\n }\n\n /**\n *\n * @param project The selected project to cleanup\n * @param keep The amount of records to keep\n * @param from Where to start cleanup\n * @param options dict options passed\n * @param options.timeout timeout limit for the request\n */\n public async gcProject(project: bigint, keep: bigint, from?: bigint, options?: { timeout?: number }): Promise<GCResult> {\n return await trace(\n \"dateilager-binary-client.gc\",\n {\n attributes: {\n \"db.mode\": \"mode\",\n \"dl.keep\": String(keep),\n \"dl.from\": String(from),\n },\n },\n async () => {\n const args = [\"--mode\", \"project\", \"--keep\", String(keep), \"--project\", String(project)];\n\n if (from) args.push(\"--from\", String(from));\n\n const result = await this._call(\"gc\", args, undefined, options);\n const parsed = JSON.parse(result.stdout) as { count: bigint };\n return { count: parsed.count };\n }\n );\n }\n\n /**\n *\n * @param sample sample size of cleanup\n * @param options dict options passed\n * @param options.timeout timeout limit for the request\n */\n public async gcContents(sample: number, options?: { timeout?: number }): Promise<GCResult> {\n return await trace(\n \"dateilager-binary-client.gc\",\n {\n attributes: {\n \"db.mode\": \"contents\",\n \"dl.sample\": String(sample),\n },\n },\n async () => {\n const args = [\"--mode\", \"contents\", \"--sample\", String(sample)];\n\n const result = await this._call(\"gc\", args, undefined, options);\n const parsed = JSON.parse(result.stdout) as { count: bigint };\n return { count: parsed.count };\n }\n );\n }\n\n /** @internal */\n private async _call(\n method: \"update\" | \"rebuild\" | \"gc\",\n args: string[],\n cwd?: string,\n options?: { timeout?: number }\n ): Promise<ExecaReturnValue> {\n const baseArgs = [method, \"--server\", this._options.server, \"--log-encoding\", \"json\"];\n\n if (this._options.logger) {\n baseArgs.push(\"--log-level\", this._options.logger.level);\n }\n\n if (this._options.tracing) {\n const carrier = {};\n propagation.inject(context.active(), carrier);\n const otelContext = JSON.stringify(carrier);\n\n baseArgs.push(\"--tracing\", \"--otel-context\", otelContext);\n }\n const subprocess = execa(this._options.command, baseArgs.concat(args), {\n cwd,\n timeout: options?.timeout ?? this._options.timeout[method],\n env: { DL_TOKEN: await this._options.token() },\n });\n\n if (this._options.logger && subprocess.stderr) {\n readline.createInterface(subprocess.stderr).on(\"line\", (line) => {\n try {\n // we purposefully extract and ignore the `ts` field\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { level, msg, ts, ...fields } = JSON.parse(line) as {\n [key: string]: unknown;\n level: \"debug\" | \"info\" | \"warn\" | \"error\";\n msg: string;\n ts: string | number;\n };\n\n this._options.logger?.log(level, msg, fields);\n } catch (error) {\n this._options.logger?.log(\"warn\", \"failed to log line\", { error, line });\n }\n });\n }\n\n return subprocess;\n }\n}\n"]}
@@ -43,6 +43,12 @@ export interface DateiLagerBinaryClientOptions {
43
43
  * @default 0 No timeout.
44
44
  */
45
45
  rebuild?: number;
46
+ /**
47
+ * The default number of milliseconds to wait before terminating the gc command.
48
+ *
49
+ * @default 0 No timeout.
50
+ */
51
+ gc?: number;
46
52
  };
47
53
  /**
48
54
  * Whether the dateilager binary client should enable tracing.
@@ -83,6 +89,15 @@ export interface RebuildResult {
83
89
  */
84
90
  patternMatch: boolean;
85
91
  }
92
+ /**
93
+ * The Result from calling the Dateilager Garbage Compiler
94
+ */
95
+ export interface GCResult {
96
+ /**
97
+ * The number of records garbage collected
98
+ */
99
+ count: bigint;
100
+ }
86
101
  /**
87
102
  * A version of the DateiLager client that uses the compiled binary client instead of the Javascript one.
88
103
  *
@@ -126,4 +141,34 @@ export declare class DateiLagerBinaryClient {
126
141
  filePattern?: string;
127
142
  filePatternIff?: boolean;
128
143
  }): Promise<RebuildResult>;
144
+ /**
145
+ * @param sample sample size of cleanup
146
+ * @param keep The amount of records to keep
147
+ * @param from Where to start cleanup
148
+ * @param options dict options passed
149
+ * @param options.timeout timeout limit for the request
150
+ */
151
+ gcRandomProjects(sample: number, keep: bigint, from?: bigint, options?: {
152
+ timeout?: number;
153
+ }): Promise<GCResult>;
154
+ /**
155
+ *
156
+ * @param project The selected project to cleanup
157
+ * @param keep The amount of records to keep
158
+ * @param from Where to start cleanup
159
+ * @param options dict options passed
160
+ * @param options.timeout timeout limit for the request
161
+ */
162
+ gcProject(project: bigint, keep: bigint, from?: bigint, options?: {
163
+ timeout?: number;
164
+ }): Promise<GCResult>;
165
+ /**
166
+ *
167
+ * @param sample sample size of cleanup
168
+ * @param options dict options passed
169
+ * @param options.timeout timeout limit for the request
170
+ */
171
+ gcContents(sample: number, options?: {
172
+ timeout?: number;
173
+ }): Promise<GCResult>;
129
174
  }
@@ -54,7 +54,8 @@ export class DateiLagerBinaryClient {
54
54
  "dl.directory": directory,
55
55
  },
56
56
  }, async () => {
57
- const result = await this._call("update", project, directory, ["--dir", directory], options);
57
+ const args = ["--dir", String(directory), "--project", String(project)];
58
+ const result = await this._call("update", args, directory, options);
58
59
  if (result.stdout == "-1") {
59
60
  return null;
60
61
  }
@@ -100,14 +101,82 @@ export class DateiLagerBinaryClient {
100
101
  args.push(`--iff=true`);
101
102
  }
102
103
  }
103
- const result = await this._call("rebuild", project, directory, args, options);
104
+ args.push("--project", String(project), "--dir", directory);
105
+ const result = await this._call("rebuild", args, directory, options);
104
106
  const parsed = JSON.parse(result.stdout);
105
107
  return { version: BigInt(parsed.version), count: parsed.count, patternMatch: parsed.patternMatch };
106
108
  });
107
109
  }
110
+ /**
111
+ * @param sample sample size of cleanup
112
+ * @param keep The amount of records to keep
113
+ * @param from Where to start cleanup
114
+ * @param options dict options passed
115
+ * @param options.timeout timeout limit for the request
116
+ */
117
+ async gcRandomProjects(sample, keep, from, options) {
118
+ return await trace("dateilager-binary-client.gc", {
119
+ attributes: {
120
+ "db.mode": "random-projects",
121
+ "dl.keep": String(keep),
122
+ "dl.from": String(from),
123
+ "dl.sample": String(sample),
124
+ },
125
+ }, async () => {
126
+ const args = ["--mode", "random-projects", "--keep", String(keep), "--sample", String(sample)];
127
+ if (from)
128
+ args.push("--from", String(from));
129
+ const result = await this._call("gc", args, undefined, options);
130
+ const parsed = JSON.parse(result.stdout);
131
+ return { count: parsed.count };
132
+ });
133
+ }
134
+ /**
135
+ *
136
+ * @param project The selected project to cleanup
137
+ * @param keep The amount of records to keep
138
+ * @param from Where to start cleanup
139
+ * @param options dict options passed
140
+ * @param options.timeout timeout limit for the request
141
+ */
142
+ async gcProject(project, keep, from, options) {
143
+ return await trace("dateilager-binary-client.gc", {
144
+ attributes: {
145
+ "db.mode": "mode",
146
+ "dl.keep": String(keep),
147
+ "dl.from": String(from),
148
+ },
149
+ }, async () => {
150
+ const args = ["--mode", "project", "--keep", String(keep), "--project", String(project)];
151
+ if (from)
152
+ args.push("--from", String(from));
153
+ const result = await this._call("gc", args, undefined, options);
154
+ const parsed = JSON.parse(result.stdout);
155
+ return { count: parsed.count };
156
+ });
157
+ }
158
+ /**
159
+ *
160
+ * @param sample sample size of cleanup
161
+ * @param options dict options passed
162
+ * @param options.timeout timeout limit for the request
163
+ */
164
+ async gcContents(sample, options) {
165
+ return await trace("dateilager-binary-client.gc", {
166
+ attributes: {
167
+ "db.mode": "contents",
168
+ "dl.sample": String(sample),
169
+ },
170
+ }, async () => {
171
+ const args = ["--mode", "contents", "--sample", String(sample)];
172
+ const result = await this._call("gc", args, undefined, options);
173
+ const parsed = JSON.parse(result.stdout);
174
+ return { count: parsed.count };
175
+ });
176
+ }
108
177
  /** @internal */
109
- async _call(method, project, cwd, args, options) {
110
- const baseArgs = [method, "--project", String(project), "--server", this._options.server, "--log-encoding", "json"];
178
+ async _call(method, args, cwd, options) {
179
+ const baseArgs = [method, "--server", this._options.server, "--log-encoding", "json"];
111
180
  if (this._options.logger) {
112
181
  baseArgs.push("--log-level", this._options.logger.level);
113
182
  }
@@ -1 +1 @@
1
- {"version":3,"file":"binary-client.js","sourceRoot":"","sources":["../../src/binary-client.ts"],"names":[],"mappings":"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","sourcesContent":["import { context, propagation } from \"@opentelemetry/api\";\nimport type { ExecaReturnValue } from \"execa\";\nimport execa from \"execa\";\nimport fs from \"fs/promises\";\nimport readline from \"readline\";\nimport { trace } from \"./internal/telemetry\";\n\n/**\n * Options for {@link DateiLagerBinaryClient}.\n */\nexport interface DateiLagerBinaryClientOptions {\n /**\n * The address of the dateilager server.\n */\n server:\n | string\n | {\n /**\n * The host of the dateilager server.\n */\n host: string;\n\n /**\n * The port of the dateilager server.\n */\n port: number;\n };\n\n /**\n * The token that will be sent as authorization metadata to the dateilager server.\n */\n token: string | (() => Promise<string>);\n\n /**\n * The path to the dateilager-client executable.\n *\n * @default \"dateilager-client\"\n */\n command?: string;\n\n /**\n * The default number of milliseconds to wait before terminating any command.\n *\n * @default 0 No timeout.\n */\n timeout?:\n | number\n | {\n /**\n * The default number of milliseconds to wait before terminating the update command.\n *\n * @default 0 No timeout.\n */\n update?: number;\n\n /**\n * The default number of milliseconds to wait before terminating the rebuild command.\n *\n * @default 0 No timeout.\n */\n rebuild?: number;\n };\n\n /**\n * Whether the dateilager binary client should enable tracing.\n *\n * @default false\n */\n tracing?: boolean;\n\n /**\n * Logging configuration.\n */\n logger?: {\n /**\n * The log level to pass to the dateilager binary client.\n */\n level: \"debug\" | \"info\" | \"warn\" | \"error\";\n\n /**\n * The function that will be called when the dateilager binary client logs something.\n */\n log: (level: \"debug\" | \"info\" | \"warn\" | \"error\", msg: string, fields: Record<string, unknown>) => void;\n };\n}\n\n/**\n * The version of the filesystem after the call to rebuild.\n *\n * If a file pattern was included then patternDetected can be used to know if that filepattern was seen while rebuilding.\n */\nexport interface RebuildResult {\n /**\n * Filesystem version.\n */\n version: bigint;\n /**\n * Files updated by the rebuild operation.\n */\n count: number;\n /**\n * Wether or not the file pattern was detected.\n */\n patternMatch: boolean;\n}\n\n/**\n * A version of the DateiLager client that uses the compiled binary client instead of the Javascript one.\n *\n * Useful for working directly with a real filesystem instead of in memory objects.\n */\nexport class DateiLagerBinaryClient {\n /** @internal */\n private readonly _options;\n\n /**\n * @param options An object with {@link DateiLagerBinaryClientOptions options}.\n */\n public constructor(options: DateiLagerBinaryClientOptions) {\n this._options = {\n server: typeof options.server === \"string\" ? options.server : `${options.server.host}:${options.server.port}`,\n token: typeof options.token === \"string\" ? () => Promise.resolve(options.token as string) : options.token,\n command: options.command ?? \"dateilager-client\",\n timeout:\n typeof options.timeout === \"number\"\n ? {\n update: options.timeout,\n rebuild: options.timeout,\n }\n : {\n update: 0,\n rebuild: 0,\n ...options.timeout,\n },\n tracing: options.tracing ?? false,\n logger: options.logger,\n };\n }\n\n /**\n * Update objects in a project based on the differences in a local directory.\n *\n * @param project The id of the project.\n * @param directory The path of the directory to send updates from.\n * @param options Object of options.\n * @param options.timeout Number of milliseconds to wait before terminating the process.\n * @returns The latest project version or `null` if something went wrong.\n */\n public async update(project: bigint, directory: string, options?: { timeout?: number }): Promise<bigint | null> {\n return await trace(\n \"dateilager-binary-client.update\",\n {\n attributes: {\n \"dl.project\": String(project),\n \"dl.directory\": directory,\n },\n },\n async () => {\n const result = await this._call(\"update\", project, directory, [\"--dir\", directory], options);\n\n if (result.stdout == \"-1\") {\n return null;\n }\n\n return BigInt(result.stdout);\n }\n );\n }\n\n /**\n * Rebuild the local filesystem.\n *\n * @param project The id of the project.\n * @param to The version of the project to rebuild the filesystem to.\n * @param directory The path of the directory to rebuild the filesystem at.\n * @param options Object of options.\n * @param options.timeout Number of milliseconds to wait before terminating the process.\n * @param options.ignores The paths to ignore when rebuilding the FS.\n * @param options.summarize Should produce the summary file after rebuilding.\n * @param options.filePattern A glob file pattern which drives the patternDetected output boolean\n * @param options.filePatternIff Should the file pattern detection trigger if and only if those files have changed\n * @returns The latest project version or `null` if something went wrong.\n */\n public async rebuild(\n project: bigint,\n to: bigint | null,\n directory: string,\n options?: { timeout?: number; ignores?: string[]; summarize?: boolean; filePattern?: string; filePatternIff?: boolean }\n ): Promise<RebuildResult> {\n return await trace(\n \"dateilager-binary-client.rebuild\",\n {\n attributes: {\n \"dl.project\": String(project),\n \"dl.to\": String(to),\n \"dl.directory\": directory,\n },\n },\n async () => {\n await fs.mkdir(directory, { recursive: true });\n\n const args = [\"--dir\", directory];\n if (to) {\n args.push(\"--to\", String(to));\n }\n\n if (options?.ignores) {\n args.push(\"--ignores\", options.ignores.join(\",\"));\n }\n\n if (options?.summarize === false) {\n args.push(\"--summarize=false\");\n }\n\n if (options?.filePattern) {\n args.push(`--filepattern=${options.filePattern}`);\n\n if (options.filePatternIff) {\n args.push(`--iff=true`);\n }\n }\n\n const result = await this._call(\"rebuild\", project, directory, args, options);\n const parsed = JSON.parse(result.stdout) as { version: number; count: number; patternMatch: boolean };\n return { version: BigInt(parsed.version), count: parsed.count, patternMatch: parsed.patternMatch };\n }\n );\n }\n\n /** @internal */\n private async _call(\n method: \"update\" | \"rebuild\",\n project: bigint,\n cwd: string,\n args: string[],\n options?: { timeout?: number }\n ): Promise<ExecaReturnValue> {\n const baseArgs = [method, \"--project\", String(project), \"--server\", this._options.server, \"--log-encoding\", \"json\"];\n\n if (this._options.logger) {\n baseArgs.push(\"--log-level\", this._options.logger.level);\n }\n\n if (this._options.tracing) {\n const carrier = {};\n propagation.inject(context.active(), carrier);\n const otelContext = JSON.stringify(carrier);\n\n baseArgs.push(\"--tracing\", \"--otel-context\", otelContext);\n }\n\n const subprocess = execa(this._options.command, baseArgs.concat(args), {\n cwd,\n timeout: options?.timeout ?? this._options.timeout[method],\n env: { DL_TOKEN: await this._options.token() },\n });\n\n if (this._options.logger && subprocess.stderr) {\n readline.createInterface(subprocess.stderr).on(\"line\", (line) => {\n try {\n // we purposefully extract and ignore the `ts` field\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { level, msg, ts, ...fields } = JSON.parse(line) as {\n [key: string]: unknown;\n level: \"debug\" | \"info\" | \"warn\" | \"error\";\n msg: string;\n ts: string | number;\n };\n\n this._options.logger?.log(level, msg, fields);\n } catch (error) {\n this._options.logger?.log(\"warn\", \"failed to log line\", { error, line });\n }\n });\n }\n\n return subprocess;\n }\n}\n"]}
1
+ {"version":3,"file":"binary-client.js","sourceRoot":"","sources":["../../src/binary-client.ts"],"names":[],"mappings":"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","sourcesContent":["import { context, propagation } from \"@opentelemetry/api\";\nimport type { ExecaReturnValue } from \"execa\";\nimport execa from \"execa\";\nimport fs from \"fs/promises\";\nimport readline from \"readline\";\nimport { trace } from \"./internal/telemetry\";\n\n/**\n * Options for {@link DateiLagerBinaryClient}.\n */\nexport interface DateiLagerBinaryClientOptions {\n /**\n * The address of the dateilager server.\n */\n server:\n | string\n | {\n /**\n * The host of the dateilager server.\n */\n host: string;\n\n /**\n * The port of the dateilager server.\n */\n port: number;\n };\n\n /**\n * The token that will be sent as authorization metadata to the dateilager server.\n */\n token: string | (() => Promise<string>);\n\n /**\n * The path to the dateilager-client executable.\n *\n * @default \"dateilager-client\"\n */\n command?: string;\n\n /**\n * The default number of milliseconds to wait before terminating any command.\n *\n * @default 0 No timeout.\n */\n timeout?:\n | number\n | {\n /**\n * The default number of milliseconds to wait before terminating the update command.\n *\n * @default 0 No timeout.\n */\n update?: number;\n\n /**\n * The default number of milliseconds to wait before terminating the rebuild command.\n *\n * @default 0 No timeout.\n */\n rebuild?: number;\n\n /**\n * The default number of milliseconds to wait before terminating the gc command.\n *\n * @default 0 No timeout.\n */\n gc?: number;\n };\n\n /**\n * Whether the dateilager binary client should enable tracing.\n *\n * @default false\n */\n tracing?: boolean;\n\n /**\n * Logging configuration.\n */\n logger?: {\n /**\n * The log level to pass to the dateilager binary client.\n */\n level: \"debug\" | \"info\" | \"warn\" | \"error\";\n\n /**\n * The function that will be called when the dateilager binary client logs something.\n */\n log: (level: \"debug\" | \"info\" | \"warn\" | \"error\", msg: string, fields: Record<string, unknown>) => void;\n };\n}\n\n/**\n * The version of the filesystem after the call to rebuild.\n *\n * If a file pattern was included then patternDetected can be used to know if that filepattern was seen while rebuilding.\n */\nexport interface RebuildResult {\n /**\n * Filesystem version.\n */\n version: bigint;\n /**\n * Files updated by the rebuild operation.\n */\n count: number;\n /**\n * Wether or not the file pattern was detected.\n */\n patternMatch: boolean;\n}\n\n/**\n * The Result from calling the Dateilager Garbage Compiler\n */\nexport interface GCResult {\n /**\n * The number of records garbage collected\n */\n count: bigint;\n}\n\n/**\n * A version of the DateiLager client that uses the compiled binary client instead of the Javascript one.\n *\n * Useful for working directly with a real filesystem instead of in memory objects.\n */\nexport class DateiLagerBinaryClient {\n /** @internal */\n private readonly _options;\n\n /**\n * @param options An object with {@link DateiLagerBinaryClientOptions options}.\n */\n public constructor(options: DateiLagerBinaryClientOptions) {\n this._options = {\n server: typeof options.server === \"string\" ? options.server : `${options.server.host}:${options.server.port}`,\n token: typeof options.token === \"string\" ? () => Promise.resolve(options.token as string) : options.token,\n command: options.command ?? \"dateilager-client\",\n timeout:\n typeof options.timeout === \"number\"\n ? {\n update: options.timeout,\n rebuild: options.timeout,\n }\n : {\n update: 0,\n rebuild: 0,\n ...options.timeout,\n },\n tracing: options.tracing ?? false,\n logger: options.logger,\n };\n }\n\n /**\n * Update objects in a project based on the differences in a local directory.\n *\n * @param project The id of the project.\n * @param directory The path of the directory to send updates from.\n * @param options Object of options.\n * @param options.timeout Number of milliseconds to wait before terminating the process.\n * @returns The latest project version or `null` if something went wrong.\n */\n public async update(project: bigint, directory: string, options?: { timeout?: number }): Promise<bigint | null> {\n return await trace(\n \"dateilager-binary-client.update\",\n {\n attributes: {\n \"dl.project\": String(project),\n \"dl.directory\": directory,\n },\n },\n async () => {\n const args = [\"--dir\", String(directory), \"--project\", String(project)];\n const result = await this._call(\"update\", args, directory, options);\n\n if (result.stdout == \"-1\") {\n return null;\n }\n\n return BigInt(result.stdout);\n }\n );\n }\n\n /**\n * Rebuild the local filesystem.\n *\n * @param project The id of the project.\n * @param to The version of the project to rebuild the filesystem to.\n * @param directory The path of the directory to rebuild the filesystem at.\n * @param options Object of options.\n * @param options.timeout Number of milliseconds to wait before terminating the process.\n * @param options.ignores The paths to ignore when rebuilding the FS.\n * @param options.summarize Should produce the summary file after rebuilding.\n * @param options.filePattern A glob file pattern which drives the patternDetected output boolean\n * @param options.filePatternIff Should the file pattern detection trigger if and only if those files have changed\n * @returns The latest project version or `null` if something went wrong.\n */\n public async rebuild(\n project: bigint,\n to: bigint | null,\n directory: string,\n options?: { timeout?: number; ignores?: string[]; summarize?: boolean; filePattern?: string; filePatternIff?: boolean }\n ): Promise<RebuildResult> {\n return await trace(\n \"dateilager-binary-client.rebuild\",\n {\n attributes: {\n \"dl.project\": String(project),\n \"dl.to\": String(to),\n \"dl.directory\": directory,\n },\n },\n async () => {\n await fs.mkdir(directory, { recursive: true });\n\n const args = [\"--dir\", directory];\n if (to) {\n args.push(\"--to\", String(to));\n }\n\n if (options?.ignores) {\n args.push(\"--ignores\", options.ignores.join(\",\"));\n }\n\n if (options?.summarize === false) {\n args.push(\"--summarize=false\");\n }\n\n if (options?.filePattern) {\n args.push(`--filepattern=${options.filePattern}`);\n\n if (options.filePatternIff) {\n args.push(`--iff=true`);\n }\n }\n\n args.push(\"--project\", String(project), \"--dir\", directory);\n const result = await this._call(\"rebuild\", args, directory, options);\n const parsed = JSON.parse(result.stdout) as { version: number; count: number; patternMatch: boolean };\n return { version: BigInt(parsed.version), count: parsed.count, patternMatch: parsed.patternMatch };\n }\n );\n }\n\n /**\n * @param sample sample size of cleanup\n * @param keep The amount of records to keep\n * @param from Where to start cleanup\n * @param options dict options passed\n * @param options.timeout timeout limit for the request\n */\n public async gcRandomProjects(sample: number, keep: bigint, from?: bigint, options?: { timeout?: number }): Promise<GCResult> {\n return await trace(\n \"dateilager-binary-client.gc\",\n {\n attributes: {\n \"db.mode\": \"random-projects\",\n \"dl.keep\": String(keep),\n \"dl.from\": String(from),\n \"dl.sample\": String(sample),\n },\n },\n async () => {\n const args = [\"--mode\", \"random-projects\", \"--keep\", String(keep), \"--sample\", String(sample)];\n\n if (from) args.push(\"--from\", String(from));\n\n const result = await this._call(\"gc\", args, undefined, options);\n const parsed = JSON.parse(result.stdout) as { count: bigint };\n return { count: parsed.count };\n }\n );\n }\n\n /**\n *\n * @param project The selected project to cleanup\n * @param keep The amount of records to keep\n * @param from Where to start cleanup\n * @param options dict options passed\n * @param options.timeout timeout limit for the request\n */\n public async gcProject(project: bigint, keep: bigint, from?: bigint, options?: { timeout?: number }): Promise<GCResult> {\n return await trace(\n \"dateilager-binary-client.gc\",\n {\n attributes: {\n \"db.mode\": \"mode\",\n \"dl.keep\": String(keep),\n \"dl.from\": String(from),\n },\n },\n async () => {\n const args = [\"--mode\", \"project\", \"--keep\", String(keep), \"--project\", String(project)];\n\n if (from) args.push(\"--from\", String(from));\n\n const result = await this._call(\"gc\", args, undefined, options);\n const parsed = JSON.parse(result.stdout) as { count: bigint };\n return { count: parsed.count };\n }\n );\n }\n\n /**\n *\n * @param sample sample size of cleanup\n * @param options dict options passed\n * @param options.timeout timeout limit for the request\n */\n public async gcContents(sample: number, options?: { timeout?: number }): Promise<GCResult> {\n return await trace(\n \"dateilager-binary-client.gc\",\n {\n attributes: {\n \"db.mode\": \"contents\",\n \"dl.sample\": String(sample),\n },\n },\n async () => {\n const args = [\"--mode\", \"contents\", \"--sample\", String(sample)];\n\n const result = await this._call(\"gc\", args, undefined, options);\n const parsed = JSON.parse(result.stdout) as { count: bigint };\n return { count: parsed.count };\n }\n );\n }\n\n /** @internal */\n private async _call(\n method: \"update\" | \"rebuild\" | \"gc\",\n args: string[],\n cwd?: string,\n options?: { timeout?: number }\n ): Promise<ExecaReturnValue> {\n const baseArgs = [method, \"--server\", this._options.server, \"--log-encoding\", \"json\"];\n\n if (this._options.logger) {\n baseArgs.push(\"--log-level\", this._options.logger.level);\n }\n\n if (this._options.tracing) {\n const carrier = {};\n propagation.inject(context.active(), carrier);\n const otelContext = JSON.stringify(carrier);\n\n baseArgs.push(\"--tracing\", \"--otel-context\", otelContext);\n }\n const subprocess = execa(this._options.command, baseArgs.concat(args), {\n cwd,\n timeout: options?.timeout ?? this._options.timeout[method],\n env: { DL_TOKEN: await this._options.token() },\n });\n\n if (this._options.logger && subprocess.stderr) {\n readline.createInterface(subprocess.stderr).on(\"line\", (line) => {\n try {\n // we purposefully extract and ignore the `ts` field\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { level, msg, ts, ...fields } = JSON.parse(line) as {\n [key: string]: unknown;\n level: \"debug\" | \"info\" | \"warn\" | \"error\";\n msg: string;\n ts: string | number;\n };\n\n this._options.logger?.log(level, msg, fields);\n } catch (error) {\n this._options.logger?.log(\"warn\", \"failed to log line\", { error, line });\n }\n });\n }\n\n return subprocess;\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gadgetinc/dateilager",
3
- "version": "0.5.3",
3
+ "version": "0.5.4",
4
4
  "homepage": "https://github.com/gadget-inc/dateilager",
5
5
  "bugs": "https://github.com/gadget-inc/dateilager/issues",
6
6
  "repository": {
@@ -43,6 +43,7 @@
43
43
  "@swc/jest": "^0.2.22",
44
44
  "@types/jest": "^29.0.0",
45
45
  "@types/node": "^18.7.16",
46
+ "@types/pg": "^8.6.6",
46
47
  "@typescript-eslint/eslint-plugin": "^5.36.2",
47
48
  "@typescript-eslint/parser": "^5.36.2",
48
49
  "eslint": "^8.23.0",
@@ -51,6 +52,7 @@
51
52
  "eslint-plugin-jest": "^27.0.2",
52
53
  "eslint-plugin-jsdoc": "^39.3.6",
53
54
  "jest": "^29.0.2",
55
+ "pg": "^8.9.0",
54
56
  "prettier": "^2.7.1",
55
57
  "prettier-plugin-packagejson": "^2.2.18",
56
58
  "typescript": "^4.7.2"