@flowscripter/pluggable-io-framework 1.2.7 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/README.md +47 -178
  2. package/dist/index.d.ts +11 -4
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +11 -4
  5. package/dist/src/concurrency/AsyncChannel.d.ts +9 -0
  6. package/dist/src/concurrency/AsyncChannel.d.ts.map +1 -0
  7. package/dist/src/concurrency/AsyncChannel.js +48 -0
  8. package/dist/src/{ConcurrencyLimiter.d.ts → concurrency/ConcurrencyLimiter.d.ts} +1 -12
  9. package/dist/src/concurrency/ConcurrencyLimiter.d.ts.map +1 -0
  10. package/dist/src/concurrency/ConcurrencyLimiter.js +64 -0
  11. package/dist/src/concurrency/mapAsyncIterableConcurrently.d.ts +13 -0
  12. package/dist/src/concurrency/mapAsyncIterableConcurrently.d.ts.map +1 -0
  13. package/dist/src/concurrency/mapAsyncIterableConcurrently.js +61 -0
  14. package/dist/src/decorators/locallyCached.d.ts +9 -10
  15. package/dist/src/decorators/locallyCached.d.ts.map +1 -1
  16. package/dist/src/decorators/locallyCached.js +23 -16
  17. package/dist/src/decorators/seekable.d.ts +4 -4
  18. package/dist/src/decorators/seekable.d.ts.map +1 -1
  19. package/dist/src/decorators/seekable.js +2 -2
  20. package/dist/src/registry/ProviderRegistry.d.ts +52 -0
  21. package/dist/src/registry/ProviderRegistry.d.ts.map +1 -0
  22. package/dist/src/registry/ProviderRegistry.js +148 -0
  23. package/dist/src/registry/detectProtocol.d.ts +8 -0
  24. package/dist/src/registry/detectProtocol.d.ts.map +1 -0
  25. package/dist/src/registry/detectProtocol.js +15 -0
  26. package/dist/src/registry/negotiateTransfer.d.ts +29 -0
  27. package/dist/src/registry/negotiateTransfer.d.ts.map +1 -0
  28. package/dist/src/registry/negotiateTransfer.js +69 -0
  29. package/dist/src/retry/RetryOptions.d.ts +19 -0
  30. package/dist/src/retry/RetryOptions.d.ts.map +1 -0
  31. package/dist/src/retry/RetryOptions.js +9 -0
  32. package/dist/src/{withRetry.d.ts → retry/withRetry.d.ts} +1 -5
  33. package/dist/src/retry/withRetry.d.ts.map +1 -0
  34. package/dist/src/{withRetry.js → retry/withRetry.js} +2 -5
  35. package/dist/src/transfer/EntryContext.d.ts +16 -0
  36. package/dist/src/transfer/EntryContext.d.ts.map +1 -0
  37. package/dist/src/transfer/EntryContext.js +1 -0
  38. package/dist/src/transfer/TransferOptions.d.ts +45 -0
  39. package/dist/src/transfer/TransferOptions.d.ts.map +1 -0
  40. package/dist/src/transfer/TransferOptions.js +1 -0
  41. package/dist/src/transfer/TransferResult.d.ts +9 -0
  42. package/dist/src/transfer/TransferResult.d.ts.map +1 -0
  43. package/dist/src/transfer/TransferResult.js +1 -0
  44. package/dist/src/transfer/aggregateResults.d.ts +4 -0
  45. package/dist/src/transfer/aggregateResults.d.ts.map +1 -0
  46. package/dist/src/transfer/aggregateResults.js +9 -0
  47. package/dist/src/transfer/copyMove.d.ts +23 -0
  48. package/dist/src/transfer/copyMove.d.ts.map +1 -0
  49. package/dist/src/transfer/copyMove.js +68 -0
  50. package/dist/src/transfer/leaseTransfer.d.ts +14 -0
  51. package/dist/src/transfer/leaseTransfer.d.ts.map +1 -0
  52. package/dist/src/transfer/leaseTransfer.js +74 -0
  53. package/dist/src/transfer/multipartTransfer.d.ts +23 -0
  54. package/dist/src/transfer/multipartTransfer.d.ts.map +1 -0
  55. package/dist/src/transfer/multipartTransfer.js +94 -0
  56. package/dist/src/transfer/negotiatePartSize.d.ts +10 -0
  57. package/dist/src/transfer/negotiatePartSize.d.ts.map +1 -0
  58. package/dist/src/transfer/negotiatePartSize.js +27 -0
  59. package/dist/src/transfer/patternTransfer.d.ts +12 -0
  60. package/dist/src/transfer/patternTransfer.d.ts.map +1 -0
  61. package/dist/src/transfer/patternTransfer.js +61 -0
  62. package/dist/src/transfer/rangeReadableMultipartReader.d.ts +8 -0
  63. package/dist/src/transfer/rangeReadableMultipartReader.d.ts.map +1 -0
  64. package/dist/src/transfer/rangeReadableMultipartReader.js +19 -0
  65. package/dist/src/transfer/recursiveTransfer.d.ts +13 -0
  66. package/dist/src/transfer/recursiveTransfer.d.ts.map +1 -0
  67. package/dist/src/transfer/recursiveTransfer.js +112 -0
  68. package/dist/src/transfer/streamTransfer.d.ts +32 -0
  69. package/dist/src/transfer/streamTransfer.d.ts.map +1 -0
  70. package/dist/src/transfer/streamTransfer.js +186 -0
  71. package/dist/src/transfer/transferEntry.d.ts +25 -0
  72. package/dist/src/transfer/transferEntry.d.ts.map +1 -0
  73. package/dist/src/transfer/transferEntry.js +136 -0
  74. package/dist/src/util/abort.d.ts +12 -0
  75. package/dist/src/util/abort.d.ts.map +1 -0
  76. package/dist/src/util/abort.js +39 -0
  77. package/dist/src/util/applyPayloadConverter.d.ts +9 -0
  78. package/dist/src/util/applyPayloadConverter.d.ts.map +1 -0
  79. package/dist/src/util/applyPayloadConverter.js +26 -0
  80. package/dist/src/util/describePath.d.ts +6 -0
  81. package/dist/src/util/describePath.d.ts.map +1 -0
  82. package/dist/src/util/describePath.js +9 -0
  83. package/dist/src/util/globToRegex.d.ts +8 -0
  84. package/dist/src/util/globToRegex.d.ts.map +1 -0
  85. package/dist/src/util/globToRegex.js +35 -0
  86. package/dist/src/util/itemLength.d.ts +4 -0
  87. package/dist/src/util/itemLength.d.ts.map +1 -0
  88. package/dist/src/util/itemLength.js +5 -0
  89. package/dist/src/util/keys.d.ts +8 -0
  90. package/dist/src/util/keys.d.ts.map +1 -0
  91. package/dist/src/util/keys.js +19 -0
  92. package/dist/src/util/withParentOperationId.d.ts +4 -0
  93. package/dist/src/util/withParentOperationId.d.ts.map +1 -0
  94. package/dist/src/util/withParentOperationId.js +12 -0
  95. package/index.ts +11 -4
  96. package/package.json +6 -5
  97. package/src/concurrency/AsyncChannel.ts +52 -0
  98. package/src/concurrency/ConcurrencyLimiter.ts +72 -0
  99. package/src/concurrency/mapAsyncIterableConcurrently.ts +66 -0
  100. package/src/decorators/locallyCached.ts +30 -22
  101. package/src/decorators/seekable.ts +7 -7
  102. package/src/registry/ProviderRegistry.ts +241 -0
  103. package/src/registry/detectProtocol.ts +16 -0
  104. package/src/registry/negotiateTransfer.ts +121 -0
  105. package/src/retry/RetryOptions.ts +26 -0
  106. package/src/{withRetry.ts → retry/withRetry.ts} +2 -12
  107. package/src/transfer/EntryContext.ts +17 -0
  108. package/src/transfer/TransferOptions.ts +45 -0
  109. package/src/transfer/TransferResult.ts +8 -0
  110. package/src/transfer/aggregateResults.ts +15 -0
  111. package/src/transfer/copyMove.ts +113 -0
  112. package/src/transfer/leaseTransfer.ts +93 -0
  113. package/src/transfer/multipartTransfer.ts +119 -0
  114. package/src/transfer/negotiatePartSize.ts +40 -0
  115. package/src/transfer/patternTransfer.ts +84 -0
  116. package/src/transfer/rangeReadableMultipartReader.ts +30 -0
  117. package/src/transfer/recursiveTransfer.ts +147 -0
  118. package/src/transfer/streamTransfer.ts +214 -0
  119. package/src/transfer/transferEntry.ts +185 -0
  120. package/src/util/abort.ts +42 -0
  121. package/src/util/applyPayloadConverter.ts +37 -0
  122. package/src/util/describePath.ts +12 -0
  123. package/src/util/globToRegex.ts +32 -0
  124. package/src/util/itemLength.ts +6 -0
  125. package/src/util/keys.ts +21 -0
  126. package/src/util/withParentOperationId.ts +17 -0
  127. package/dist/src/ConcurrencyLimiter.d.ts.map +0 -1
  128. package/dist/src/ConcurrencyLimiter.js +0 -161
  129. package/dist/src/ProviderRegistry.d.ts +0 -14
  130. package/dist/src/ProviderRegistry.d.ts.map +0 -1
  131. package/dist/src/ProviderRegistry.js +0 -22
  132. package/dist/src/chunkLength.d.ts +0 -3
  133. package/dist/src/chunkLength.d.ts.map +0 -1
  134. package/dist/src/chunkLength.js +0 -4
  135. package/dist/src/copyMove.d.ts +0 -46
  136. package/dist/src/copyMove.d.ts.map +0 -1
  137. package/dist/src/copyMove.js +0 -280
  138. package/dist/src/withRetry.d.ts.map +0 -1
  139. package/src/ConcurrencyLimiter.ts +0 -178
  140. package/src/ProviderRegistry.ts +0 -32
  141. package/src/chunkLength.ts +0 -5
  142. package/src/copyMove.ts +0 -458
@@ -0,0 +1,42 @@
1
+ /** The error a transfer rejects with when cancelled through `TransferOptions.signal`. */
2
+ export function createAbortError(): DOMException {
3
+ return new DOMException("The transfer was aborted", "AbortError");
4
+ }
5
+
6
+ export function throwIfAborted(signal: AbortSignal | undefined): void {
7
+ if (signal?.aborted) {
8
+ throw createAbortError();
9
+ }
10
+ }
11
+
12
+ /**
13
+ * Resolves with `"aborted"` or `"stopped"` as soon as `signal` or `stop`
14
+ * fires, and never otherwise. `dispose` removes the listeners.
15
+ */
16
+ export function watchSignals(
17
+ signal: AbortSignal | undefined,
18
+ stop: AbortSignal | undefined,
19
+ ): { readonly fired: Promise<"aborted" | "stopped">; dispose(): void } {
20
+ const cleanups: (() => void)[] = [];
21
+ const fired = new Promise<"aborted" | "stopped">((resolve) => {
22
+ for (const [target, outcome] of [
23
+ [signal, "aborted"],
24
+ [stop, "stopped"],
25
+ ] as const) {
26
+ if (!target) continue;
27
+ if (target.aborted) {
28
+ resolve(outcome);
29
+ continue;
30
+ }
31
+ const listener = () => resolve(outcome);
32
+ target.addEventListener("abort", listener, { once: true });
33
+ cleanups.push(() => target.removeEventListener("abort", listener));
34
+ }
35
+ });
36
+ return {
37
+ fired,
38
+ dispose() {
39
+ for (const cleanup of cleanups) cleanup();
40
+ },
41
+ };
42
+ }
@@ -0,0 +1,37 @@
1
+ import {
2
+ adaptReadableStream,
3
+ type Item,
4
+ type PayloadConverter,
5
+ type PayloadKind,
6
+ } from "@flowscripter/pluggable-io-framework-api";
7
+
8
+ /**
9
+ * Converts every item of `stream` for a sink of `toKind`. With a converter,
10
+ * each item goes through `converter.convert`, including when the kinds match
11
+ * and only the memory domain differs. Without one, a kind mismatch fails on
12
+ * the first item.
13
+ */
14
+ export function applyPayloadConverter(
15
+ stream: ReadableStream<Item>,
16
+ fromKind: PayloadKind,
17
+ toKind: PayloadKind,
18
+ converter: PayloadConverter | undefined,
19
+ ): ReadableStream<Item> {
20
+ if (!converter) {
21
+ return adaptReadableStream(stream, fromKind, toKind);
22
+ }
23
+ const reader = stream.getReader();
24
+ return new ReadableStream<Item>({
25
+ async pull(controller) {
26
+ const { done, value } = await reader.read();
27
+ if (done) {
28
+ controller.close();
29
+ return;
30
+ }
31
+ controller.enqueue(converter.convert(value));
32
+ },
33
+ cancel(reason) {
34
+ return reader.cancel(reason);
35
+ },
36
+ });
37
+ }
@@ -0,0 +1,12 @@
1
+ import type { PayloadConverter, PayloadKind } from "@flowscripter/pluggable-io-framework-api";
2
+
3
+ /** `kind` or `kind[domain]`. */
4
+ export function describeKind(kind: PayloadKind, domain?: string): string {
5
+ return domain === undefined ? kind : `${kind}[${domain}]`;
6
+ }
7
+
8
+ /** ` via from->to (zero-copy)` or ` via from->to (copy)`. */
9
+ export function describeConverter(converter: PayloadConverter): string {
10
+ const cost = converter.cost === 0 ? "zero-copy" : "copy";
11
+ return ` via ${describeKind(converter.from.kind, converter.from.domain)}->${describeKind(converter.to.kind, converter.to.domain)} (${cost})`;
12
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Translates a glob into an anchored regular expression matched against a
3
+ * single entry name: `*` matches any run of characters except `/`, `?`
4
+ * matches one such character, and `[...]` is a character class (`[!...]`
5
+ * negates it). Everything else matches literally.
6
+ */
7
+ export function globToRegex(glob: string): RegExp {
8
+ let source = "";
9
+ for (let i = 0; i < glob.length; i += 1) {
10
+ const char = glob[i] as string;
11
+ if (char === "*") {
12
+ source += "[^/]*";
13
+ } else if (char === "?") {
14
+ source += "[^/]";
15
+ } else if (char === "[") {
16
+ const close = glob.indexOf("]", i + 2);
17
+ if (close === -1) {
18
+ source += "\\[";
19
+ continue;
20
+ }
21
+ let body = glob.slice(i + 1, close);
22
+ if (body.startsWith("!")) {
23
+ body = `^${body.slice(1)}`;
24
+ }
25
+ source += `[${body.replace(/\\/g, "\\\\")}]`;
26
+ i = close;
27
+ } else {
28
+ source += char.replace(/[.+^${}()|\\/\]]/g, "\\$&");
29
+ }
30
+ }
31
+ return new RegExp(`^${source}$`);
32
+ }
@@ -0,0 +1,6 @@
1
+ import { type Item, PayloadKind } from "@flowscripter/pluggable-io-framework-api";
2
+
3
+ /** The payload size of an item in bytes. */
4
+ export function itemLength(item: Item): number {
5
+ return item.payload.kind === PayloadKind.Js ? item.payload.data.byteLength : item.payload.length;
6
+ }
@@ -0,0 +1,21 @@
1
+ import type { IOProvider } from "@flowscripter/pluggable-io-framework-api";
2
+
3
+ /** Joins with `/` - the default when a provider has no `joinKey`. */
4
+ export function defaultJoinKey(containerKey: string, name: string): string {
5
+ if (name === "") return containerKey;
6
+ if (containerKey === "") return name;
7
+ return `${containerKey.replace(/\/+$/, "")}/${name}`;
8
+ }
9
+
10
+ /** Joins a child name onto a container key using the provider's own rule. */
11
+ export function joinKey(provider: IOProvider, containerKey: string, name: string): string {
12
+ return provider.joinKey
13
+ ? provider.joinKey(containerKey, name)
14
+ : defaultJoinKey(containerKey, name);
15
+ }
16
+
17
+ /** The last segment of a key, treating both `/` and `\` as separators. */
18
+ export function baseName(key: string): string {
19
+ const segments = key.split(/[\\/]+/).filter((segment) => segment !== "");
20
+ return segments.at(-1) ?? key;
21
+ }
@@ -0,0 +1,17 @@
1
+ import type { TelemetryHooks } from "@flowscripter/pluggable-io-framework-api";
2
+
3
+ /** Wraps `hooks` so any `onProgress` event passing through gets `parentOperationId` filled in, unless the emitter already set one (nested hierarchy). */
4
+ export function withParentOperationId(
5
+ hooks: TelemetryHooks | undefined,
6
+ parentOperationId: string | undefined,
7
+ ): TelemetryHooks {
8
+ if (!hooks || parentOperationId === undefined) {
9
+ return hooks ?? {};
10
+ }
11
+ return {
12
+ ...hooks,
13
+ onProgress: hooks.onProgress
14
+ ? (event) => hooks.onProgress?.({ parentOperationId, ...event })
15
+ : undefined,
16
+ };
17
+ }
@@ -1 +0,0 @@
1
- {"version":3,"file":"ConcurrencyLimiter.d.ts","sourceRoot":"","sources":["../../src/ConcurrencyLimiter.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,qBAAa,kBAAkB;;IAK7B,YAAmB,cAAc,EAAE,MAAM,EAGxC;IAED,IAAW,cAAc,IAAI,MAAM,CAElC;IAEM,iBAAiB,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAIrD;IAEY,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAQpD;CA0BF;AAED;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,oBAAkD,CAAC;AAuDzF;;;;;;;;;GASG;AACH,wBAAgB,4BAA4B,CAAC,CAAC,EAAE,CAAC,EAC/C,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,EACxB,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,EAC3B,OAAO,EAAE,kBAAkB,GAC1B,aAAa,CAAC,CAAC,CAAC,CAqClB"}
@@ -1,161 +0,0 @@
1
- const DEFAULT_MAX_CONCURRENCY = 4;
2
- /**
3
- * A semaphore bounding how many `run()` callbacks execute at once. A single
4
- * shared instance (see {@link defaultConcurrencyLimiter}) enforces its cap
5
- * *globally* across concurrently invoked `copy()`/`move()` calls, not just
6
- * within one call - two folder copies started at the same time and sharing
7
- * a limiter will never together exceed its `maxConcurrency`.
8
- */
9
- export class ConcurrencyLimiter {
10
- #maxConcurrency;
11
- #active = 0;
12
- #queue = [];
13
- constructor(maxConcurrency) {
14
- ConcurrencyLimiter.#validate(maxConcurrency);
15
- this.#maxConcurrency = maxConcurrency;
16
- }
17
- get maxConcurrency() {
18
- return this.#maxConcurrency;
19
- }
20
- setMaxConcurrency(maxConcurrency) {
21
- ConcurrencyLimiter.#validate(maxConcurrency);
22
- this.#maxConcurrency = maxConcurrency;
23
- this.#drain();
24
- }
25
- async run(fn) {
26
- await this.#acquire();
27
- try {
28
- return await fn();
29
- }
30
- finally {
31
- this.#active -= 1;
32
- this.#drain();
33
- }
34
- }
35
- #acquire() {
36
- if (this.#active < this.#maxConcurrency) {
37
- this.#active += 1;
38
- return Promise.resolve();
39
- }
40
- return new Promise((resolve) => {
41
- this.#queue.push(() => {
42
- this.#active += 1;
43
- resolve();
44
- });
45
- });
46
- }
47
- #drain() {
48
- while (this.#active < this.#maxConcurrency && this.#queue.length > 0) {
49
- this.#queue.shift()?.();
50
- }
51
- }
52
- static #validate(maxConcurrency) {
53
- if (!Number.isInteger(maxConcurrency) || maxConcurrency < 1) {
54
- throw new Error(`maxConcurrency must be a positive integer, got ${maxConcurrency}`);
55
- }
56
- }
57
- }
58
- /**
59
- * Process-wide default limiter, used by `copy()`/`move()` whenever
60
- * `TransferOptions.concurrencyLimiter` is omitted - so any two calls in the
61
- * same process share one cap unless a caller explicitly opts out with its
62
- * own instance (e.g. for test isolation).
63
- */
64
- export const defaultConcurrencyLimiter = new ConcurrencyLimiter(DEFAULT_MAX_CONCURRENCY);
65
- /** Minimal single-consumer async FIFO queue backing {@link mapAsyncIterableConcurrently}. */
66
- class AsyncChannel {
67
- #items = [];
68
- #waiters = [];
69
- #closed = false;
70
- #hasError = false;
71
- #error;
72
- push(item) {
73
- const waiter = this.#waiters.shift();
74
- if (waiter) {
75
- waiter.resolve({ value: item, done: false });
76
- }
77
- else {
78
- this.#items.push(item);
79
- }
80
- }
81
- close() {
82
- this.#closed = true;
83
- for (const waiter of this.#waiters.splice(0)) {
84
- if (this.#hasError) {
85
- waiter.reject(this.#error);
86
- }
87
- else {
88
- waiter.resolve({ value: undefined, done: true });
89
- }
90
- }
91
- }
92
- fail(error) {
93
- this.#hasError = true;
94
- this.#error = error;
95
- this.close();
96
- }
97
- async #next() {
98
- if (this.#items.length > 0) {
99
- return { value: this.#items.shift(), done: false };
100
- }
101
- if (this.#closed) {
102
- if (this.#hasError) {
103
- throw this.#error;
104
- }
105
- return { value: undefined, done: true };
106
- }
107
- return new Promise((resolve, reject) => this.#waiters.push({ resolve, reject }));
108
- }
109
- [Symbol.asyncIterator]() {
110
- return { next: () => this.#next() };
111
- }
112
- }
113
- /**
114
- * Pulls items from `source` and runs `fn` on each, bounded by `limiter`:
115
- * exactly `limiter.maxConcurrency` worker loops each pull-then-process one
116
- * item at a time through `limiter.run`, so at most that many items are ever
117
- * pulled/in-flight at once (important for sources like a multipart reader
118
- * where pulling an item eagerly opens a file/network handle). Results are
119
- * yielded in completion order, not source order. If `fn` throws, no new
120
- * items are pulled but already-in-flight ones are allowed to finish before
121
- * the error is rethrown from the returned iterable.
122
- */
123
- export function mapAsyncIterableConcurrently(source, fn, limiter) {
124
- const channel = new AsyncChannel();
125
- const iterator = source[Symbol.asyncIterator]();
126
- let stopped = false;
127
- let firstError;
128
- let errorRecorded = false;
129
- async function worker() {
130
- for (;;) {
131
- if (stopped)
132
- return;
133
- const { done, value } = await iterator.next();
134
- if (done)
135
- return;
136
- try {
137
- const result = await limiter.run(() => fn(value));
138
- channel.push(result);
139
- }
140
- catch (error) {
141
- stopped = true;
142
- if (!errorRecorded) {
143
- errorRecorded = true;
144
- firstError = error;
145
- }
146
- return;
147
- }
148
- }
149
- }
150
- void (async () => {
151
- const workerCount = Math.max(1, limiter.maxConcurrency);
152
- await Promise.all(Array.from({ length: workerCount }, () => worker()));
153
- if (errorRecorded) {
154
- channel.fail(firstError);
155
- }
156
- else {
157
- channel.close();
158
- }
159
- })();
160
- return channel;
161
- }
@@ -1,14 +0,0 @@
1
- import type { PluginManager } from "@flowscripter/dynamic-plugin-framework";
2
- import { type IOProvider } from "@flowscripter/pluggable-io-framework-api";
3
- /**
4
- * Wraps a `dynamic-plugin-framework` {@link PluginManager} to discover and
5
- * instantiate pluggable-io-framework source/sink provider plugins.
6
- */
7
- export declare class ProviderRegistry {
8
- private readonly pluginManager;
9
- constructor(pluginManager: PluginManager);
10
- discover(): Promise<void>;
11
- listAvailableProviders(): Promise<readonly import("@flowscripter/dynamic-plugin-framework").ExtensionInfo[]>;
12
- createProvider(extensionHandle: string, config: unknown): Promise<IOProvider>;
13
- }
14
- //# sourceMappingURL=ProviderRegistry.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ProviderRegistry.d.ts","sourceRoot":"","sources":["../../src/ProviderRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAC;AAC5E,OAAO,EAEL,KAAK,UAAU,EAEhB,MAAM,0CAA0C,CAAC;AAElD;;;GAGG;AACH,qBAAa,gBAAgB;IACR,OAAO,CAAC,QAAQ,CAAC,aAAa;IAAjD,YAAoC,aAAa,EAAE,aAAa,EAAI;IAEvD,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAIrC;IAEY,sBAAsB,uFAIlC;IAEY,cAAc,CAAC,eAAe,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,CAIzF;CACF"}
@@ -1,22 +0,0 @@
1
- import { PLUGGABLE_IO_FRAMEWORK_PROVIDER_FACTORY_EXTENSION_POINT, } from "@flowscripter/pluggable-io-framework-api";
2
- /**
3
- * Wraps a `dynamic-plugin-framework` {@link PluginManager} to discover and
4
- * instantiate pluggable-io-framework source/sink provider plugins.
5
- */
6
- export class ProviderRegistry {
7
- pluginManager;
8
- constructor(pluginManager) {
9
- this.pluginManager = pluginManager;
10
- }
11
- async discover() {
12
- await this.pluginManager.registerExtensions(PLUGGABLE_IO_FRAMEWORK_PROVIDER_FACTORY_EXTENSION_POINT);
13
- }
14
- async listAvailableProviders() {
15
- return this.pluginManager.getRegisteredExtensions(PLUGGABLE_IO_FRAMEWORK_PROVIDER_FACTORY_EXTENSION_POINT);
16
- }
17
- async createProvider(extensionHandle, config) {
18
- const factory = (await this.pluginManager.instantiate(extensionHandle));
19
- const validatedConfig = factory.configSchema.parse(config);
20
- return factory.createProvider(validatedConfig);
21
- }
22
- }
@@ -1,3 +0,0 @@
1
- import { type ChunkRef } from "@flowscripter/pluggable-io-framework-api";
2
- export declare function chunkLength(chunk: ChunkRef): number;
3
- //# sourceMappingURL=chunkLength.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"chunkLength.d.ts","sourceRoot":"","sources":["../../src/chunkLength.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,QAAQ,EAAE,MAAM,0CAA0C,CAAC;AAEpF,wBAAgB,WAAW,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAEnD"}
@@ -1,4 +0,0 @@
1
- import { ChunkKind } from "@flowscripter/pluggable-io-framework-api";
2
- export function chunkLength(chunk) {
3
- return chunk.kind === ChunkKind.Js ? chunk.data.byteLength : chunk.length;
4
- }
@@ -1,46 +0,0 @@
1
- import { type ChunkConverter, type IOProvider, type TelemetryHooks } from "@flowscripter/pluggable-io-framework-api";
2
- import { type ConcurrencyLimiter } from "./ConcurrencyLimiter.ts";
3
- import { type RetryOptions } from "./withRetry.ts";
4
- export interface TransferOptions {
5
- readonly telemetry?: TelemetryHooks;
6
- /** Minimum file size (bytes) before multipart transfer is attempted over plain streaming. */
7
- readonly multipartThreshold?: number;
8
- /**
9
- * Required only when `source.kind !== sink.kind` - pure-TS code can only
10
- * convert chunks already of the target kind (see
11
- * `identityChunkConverter`); a real js<->native conversion needs an
12
- * FFI-capable converter supplied by a runtime-specific package.
13
- */
14
- readonly chunkConverter?: ChunkConverter;
15
- /**
16
- * Bounds concurrent multipart parts and recursive-copy/move entries.
17
- * Defaults to the shared {@link defaultConcurrencyLimiter} - so two
18
- * `copy()`/`move()` calls in the same process share one cap unless a
19
- * caller passes its own isolated instance.
20
- */
21
- readonly concurrencyLimiter?: ConcurrencyLimiter;
22
- /** Retry policy for the non-direct transfer path. Defaults to `{ maxRetries: 3 }`. */
23
- readonly retry?: RetryOptions;
24
- }
25
- /**
26
- * Copies `sourcePath` on `source` to `destPath` on `sink`. When `sourcePath`
27
- * is a folder, recurses: uses a folder-aware `directCopy` when the source
28
- * declares `supportsRecursiveDirectTransfer`, otherwise lists the folder and
29
- * transfers each entry (bounded by `options.concurrencyLimiter`), following
30
- * `cp -r` target semantics (see {@link resolveRecursiveDestRoot}).
31
- *
32
- * For a single file: uses `source.directCopy` when
33
- * `source.canDirectTransfer?.(sink)` reports eligibility. Otherwise falls
34
- * back to multipart transfer (when both sides support it, size crosses
35
- * `options.multipartThreshold`, and part-size negotiation succeeds) or plain
36
- * streaming - retried per `options.retry` on `TransientIOError`.
37
- */
38
- export declare function copy(source: IOProvider, sourcePath: string, sink: IOProvider, destPath: string, options?: TransferOptions): Promise<void>;
39
- /**
40
- * Moves `sourcePath` on `source` to `destPath` on `sink`. Folder handling
41
- * mirrors {@link copy}. For a single file, uses `source.directMove` when
42
- * eligible, otherwise performs a {@link copy} followed by deleting the
43
- * source item (each retried independently per `options.retry`).
44
- */
45
- export declare function move(source: IOProvider, sourcePath: string, sink: IOProvider, destPath: string, options?: TransferOptions): Promise<void>;
46
- //# sourceMappingURL=copyMove.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"copyMove.d.ts","sourceRoot":"","sources":["../../src/copyMove.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,cAAc,EAEnB,KAAK,UAAU,EAIf,KAAK,cAAc,EACpB,MAAM,0CAA0C,CAAC;AAElD,OAAO,EACL,KAAK,kBAAkB,EAGxB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAa,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9D,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,SAAS,CAAC,EAAE,cAAc,CAAC;IACpC,6FAA6F;IAC7F,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC;;;;;OAKG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,cAAc,CAAC;IACzC;;;;;OAKG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACjD,sFAAsF;IACtF,QAAQ,CAAC,KAAK,CAAC,EAAE,YAAY,CAAC;CAC/B;AAmXD;;;;;;;;;;;;GAYG;AACH,wBAAsB,IAAI,CACxB,MAAM,EAAE,UAAU,EAClB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,IAAI,CAAC,CAOf;AAED;;;;;GAKG;AACH,wBAAsB,IAAI,CACxB,MAAM,EAAE,UAAU,EAClB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,IAAI,CAAC,CAOf"}