@chunkd/source 11.0.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/LICENSE +21 -0
- package/README.md +49 -0
- package/build/src/__test__/range.test.d.ts +1 -0
- package/build/src/__test__/range.test.js +18 -0
- package/build/src/__test__/range.test.js.map +1 -0
- package/build/src/error.d.ts +12 -0
- package/build/src/error.js +31 -0
- package/build/src/error.js.map +1 -0
- package/build/src/index.d.ts +6 -0
- package/build/src/index.js +12 -0
- package/build/src/index.js.map +1 -0
- package/build/src/middleware.d.ts +11 -0
- package/build/src/middleware.js +2 -0
- package/build/src/middleware.js.map +1 -0
- package/build/src/range.d.ts +10 -0
- package/build/src/range.js +28 -0
- package/build/src/range.js.map +1 -0
- package/build/src/source.d.ts +43 -0
- package/build/src/source.js +2 -0
- package/build/src/source.js.map +1 -0
- package/build/src/view.d.ts +21 -0
- package/build/src/view.js +53 -0
- package/build/src/view.js.map +1 -0
- package/package.json +30 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2021 Blayne Chard
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# @chunkd/source
|
|
2
|
+
|
|
3
|
+
Base interface for all sources used by `@chunkd`
|
|
4
|
+
|
|
5
|
+
````typescript
|
|
6
|
+
export interface Source {
|
|
7
|
+
/**
|
|
8
|
+
* human friendly name of the source type
|
|
9
|
+
* @example "aws:s3", "file", "memory"
|
|
10
|
+
*/
|
|
11
|
+
type: string;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* URL to the source
|
|
15
|
+
*
|
|
16
|
+
* @example "s3://linz-imagery/catalog.json" or "file:///home/blacha/18_126359_137603.webp"
|
|
17
|
+
*/
|
|
18
|
+
url: URL;
|
|
19
|
+
|
|
20
|
+
/** Metadata about the object the source represents */
|
|
21
|
+
metadata?: SourceMetadata;
|
|
22
|
+
|
|
23
|
+
/** Read the metadata before a fetch request */
|
|
24
|
+
head(): Promise<SourceMetadata>;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Directly read bytes from the source
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```typescript
|
|
31
|
+
* source.fetch(0, 1024) // load the first 1024 bytes
|
|
32
|
+
* source.fetch(1024, 20) // read 20 bytes at offset 1024
|
|
33
|
+
* source.fetch(-1024) // load the last 1024 bytes
|
|
34
|
+
*```
|
|
35
|
+
* @param offset Byte to start reading form
|
|
36
|
+
* @param length optional number of bytes to read
|
|
37
|
+
*/
|
|
38
|
+
fetch(offset: number, length?: number): Promise<ArrayBuffer>;
|
|
39
|
+
}
|
|
40
|
+
````
|
|
41
|
+
|
|
42
|
+
## Examples
|
|
43
|
+
|
|
44
|
+
Example sources
|
|
45
|
+
|
|
46
|
+
- [Memory](https://www.npmjs.com/package/@chunkd/source-memory)
|
|
47
|
+
- [File](https://www.npmjs.com/package/@chunkd/source-file)
|
|
48
|
+
- [AWS](https://www.npmjs.com/package/@chunkd/source-aws)
|
|
49
|
+
- [Http](https://www.npmjs.com/package/@chunkd/source-http)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import assert from 'node:assert';
|
|
2
|
+
import { describe, it } from 'node:test';
|
|
3
|
+
import { ContentRange } from '../range.js';
|
|
4
|
+
describe('ContentRange', () => {
|
|
5
|
+
it('should create a range request', () => {
|
|
6
|
+
assert.equal(ContentRange.toRange(0, 1024), 'bytes=0-1023');
|
|
7
|
+
});
|
|
8
|
+
it('should parse size from range response', () => {
|
|
9
|
+
assert.equal(ContentRange.parseSize('bytes 0-1024/46661'), 46661);
|
|
10
|
+
assert.equal(ContentRange.parseSize('bytes */30'), 30);
|
|
11
|
+
});
|
|
12
|
+
it('should throw on badly formated ranges', () => {
|
|
13
|
+
assert.throws(() => ContentRange.parseSize(''));
|
|
14
|
+
assert.throws(() => ContentRange.parseSize('test 1234'));
|
|
15
|
+
assert.throws(() => ContentRange.parseSize('bytes 0-1024/*'));
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
//# sourceMappingURL=range.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"range.test.js","sourceRoot":"","sources":["../../../src/__test__/range.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,cAAc,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC,oBAAoB,CAAC,EAAE,KAAK,CAAC,CAAC;QAClE,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC,YAAY,CAAC,EAAE,EAAE,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC;QAChD,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC;QACzD,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Source } from './source.js';
|
|
2
|
+
export declare class SourceError extends Error {
|
|
3
|
+
/** Status code for the error eg 403 - Forbidden vs 404 Not found */
|
|
4
|
+
readonly code: number;
|
|
5
|
+
/** URL that the status code came from */
|
|
6
|
+
readonly url: URL;
|
|
7
|
+
/** File system that triggered the error */
|
|
8
|
+
readonly source: Source;
|
|
9
|
+
constructor(msg: string, code: number, source: Source, cause?: unknown);
|
|
10
|
+
/** Check that a unknown is a FsError */
|
|
11
|
+
static is(e: unknown): e is SourceError;
|
|
12
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export class SourceError extends Error {
|
|
2
|
+
/** Status code for the error eg 403 - Forbidden vs 404 Not found */
|
|
3
|
+
code;
|
|
4
|
+
/** URL that the status code came from */
|
|
5
|
+
url;
|
|
6
|
+
/** File system that triggered the error */
|
|
7
|
+
source;
|
|
8
|
+
constructor(msg, code, source, cause) {
|
|
9
|
+
super(msg, { cause });
|
|
10
|
+
this.code = code;
|
|
11
|
+
this.url = source.url;
|
|
12
|
+
this.source = source;
|
|
13
|
+
/** Helper to determine if this class is a SourceError, useful for when `instanceof` fails */
|
|
14
|
+
Object.defineProperty(this, '_sourceError', {
|
|
15
|
+
enumerable: false,
|
|
16
|
+
value: 'SourceError',
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
/** Check that a unknown is a FsError */
|
|
20
|
+
static is(e) {
|
|
21
|
+
if (e instanceof SourceError)
|
|
22
|
+
return true;
|
|
23
|
+
// Sometimes instanceof fails, so fall back to checking for a `_sourceError` key
|
|
24
|
+
if (typeof e !== 'object')
|
|
25
|
+
return false;
|
|
26
|
+
if (e == null)
|
|
27
|
+
return false;
|
|
28
|
+
return '_sourceError' in e && e['_sourceError'] === 'SourceError';
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.js","sourceRoot":"","sources":["../../src/error.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,WAAY,SAAQ,KAAK;IACpC,oEAAoE;IAC3D,IAAI,CAAS;IACtB,yCAAyC;IAChC,GAAG,CAAM;IAClB,2CAA2C;IAClC,MAAM,CAAS;IAExB,YAAY,GAAW,EAAE,IAAY,EAAE,MAAc,EAAE,KAAe;QACpE,KAAK,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QACtB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC;QACtB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QAErB,6FAA6F;QAC7F,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,cAAc,EAAE;YAC1C,UAAU,EAAE,KAAK;YACjB,KAAK,EAAE,aAAa;SACrB,CAAC,CAAC;IACL,CAAC;IAED,wCAAwC;IACxC,MAAM,CAAC,EAAE,CAAC,CAAU;QAClB,IAAI,CAAC,YAAY,WAAW;YAAE,OAAO,IAAI,CAAC;QAC1C,gFAAgF;QAChF,IAAI,OAAO,CAAC,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC;QACxC,IAAI,CAAC,IAAI,IAAI;YAAE,OAAO,KAAK,CAAC;QAC5B,OAAO,cAAc,IAAI,CAAC,IAAI,CAAC,CAAC,cAAc,CAAC,KAAK,aAAa,CAAC;IACpE,CAAC;CACF"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { SourceError } from './error.js';
|
|
2
|
+
export { SourceCallback, SourceMiddleware, SourceRequest } from './middleware.js';
|
|
3
|
+
export { ContentRange } from './range.js';
|
|
4
|
+
export { Source, SourceMetadata } from './source.js';
|
|
5
|
+
export { SourceView } from './view.js';
|
|
6
|
+
export declare function tryParseUrl(s: string): URL | null;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { SourceError } from './error.js';
|
|
2
|
+
export { ContentRange } from './range.js';
|
|
3
|
+
export { SourceView } from './view.js';
|
|
4
|
+
export function tryParseUrl(s) {
|
|
5
|
+
try {
|
|
6
|
+
return new URL(s);
|
|
7
|
+
}
|
|
8
|
+
catch (e) {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC,MAAM,UAAU,WAAW,CAAC,CAAS;IACnC,IAAI;QACF,OAAO,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;KACnB;IAAC,OAAO,CAAC,EAAE;QACV,OAAO,IAAI,CAAC;KACb;AACH,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Source } from './source.js';
|
|
2
|
+
export interface SourceRequest {
|
|
3
|
+
source: Source;
|
|
4
|
+
offset: number;
|
|
5
|
+
length: number | undefined;
|
|
6
|
+
}
|
|
7
|
+
export type SourceCallback = (req: SourceRequest) => Promise<ArrayBuffer>;
|
|
8
|
+
export interface SourceMiddleware {
|
|
9
|
+
name: string;
|
|
10
|
+
fetch(req: SourceRequest, next: SourceCallback): Promise<ArrayBuffer>;
|
|
11
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../src/middleware.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const ContentRange: {
|
|
2
|
+
/** Convert a offset/length to a range request */
|
|
3
|
+
toRange(offset: number, length?: number): string;
|
|
4
|
+
/**
|
|
5
|
+
* Parse a common Content-Range header to extract the size of the source
|
|
6
|
+
* @example Content-Range: bytes 200-1000/67589
|
|
7
|
+
* @throws if range is not a Content-Range with size
|
|
8
|
+
*/
|
|
9
|
+
parseSize(range: string): number;
|
|
10
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export const ContentRange = {
|
|
2
|
+
/** Convert a offset/length to a range request */
|
|
3
|
+
toRange(offset, length) {
|
|
4
|
+
if (length == null)
|
|
5
|
+
return `bytes=${offset}`;
|
|
6
|
+
if (offset < 0)
|
|
7
|
+
throw new Error('Cannot read from remote source with negative offset and length');
|
|
8
|
+
return `bytes=${offset}-${offset + length - 1}`;
|
|
9
|
+
},
|
|
10
|
+
/**
|
|
11
|
+
* Parse a common Content-Range header to extract the size of the source
|
|
12
|
+
* @example Content-Range: bytes 200-1000/67589
|
|
13
|
+
* @throws if range is not a Content-Range with size
|
|
14
|
+
*/
|
|
15
|
+
parseSize(range) {
|
|
16
|
+
const [unit, chunks] = range.split(' ');
|
|
17
|
+
if (unit !== 'bytes')
|
|
18
|
+
throw new Error('Failed to parse content-range: ' + range);
|
|
19
|
+
if (chunks == null)
|
|
20
|
+
throw new Error('Failed to parse content-range: ' + range);
|
|
21
|
+
const [, size] = chunks.split('/');
|
|
22
|
+
const result = Number(size);
|
|
23
|
+
if (isNaN(result))
|
|
24
|
+
throw new Error('Failed to parse content-range: ' + range);
|
|
25
|
+
return result;
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=range.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"range.js","sourceRoot":"","sources":["../../src/range.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,iDAAiD;IACjD,OAAO,CAAC,MAAc,EAAE,MAAe;QACrC,IAAI,MAAM,IAAI,IAAI;YAAE,OAAO,SAAS,MAAM,EAAE,CAAC;QAC7C,IAAI,MAAM,GAAG,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;QAClG,OAAO,SAAS,MAAM,IAAI,MAAM,GAAG,MAAM,GAAG,CAAC,EAAE,CAAC;IAClD,CAAC;IAED;;;;OAIG;IACH,SAAS,CAAC,KAAa;QACrB,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACxC,IAAI,IAAI,KAAK,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,GAAG,KAAK,CAAC,CAAC;QACjF,IAAI,MAAM,IAAI,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,GAAG,KAAK,CAAC,CAAC;QAC/E,MAAM,CAAC,EAAE,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACnC,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QAC5B,IAAI,KAAK,CAAC,MAAM,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,GAAG,KAAK,CAAC,CAAC;QAC9E,OAAO,MAAM,CAAC;IAChB,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export interface Source {
|
|
2
|
+
/**
|
|
3
|
+
* human friendly name of the source type
|
|
4
|
+
* @example "aws:s3", "file", "memory"
|
|
5
|
+
*/
|
|
6
|
+
type: string;
|
|
7
|
+
/**
|
|
8
|
+
* URL to the source
|
|
9
|
+
*
|
|
10
|
+
* @example "s3://linz-imagery/catalog.json" or "file:///home/blacha/18_126359_137603.webp"
|
|
11
|
+
*/
|
|
12
|
+
url: URL;
|
|
13
|
+
/** Metadata about the object the source represents */
|
|
14
|
+
metadata?: SourceMetadata;
|
|
15
|
+
/** Read the metadata before a fetch request */
|
|
16
|
+
head(): Promise<SourceMetadata>;
|
|
17
|
+
/** close the source, sources like files sometimes have open file handles that need to be closed */
|
|
18
|
+
close?(): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Directly read bytes from the source
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* source.fetch(0, 1024) // load the first 1024 bytes
|
|
25
|
+
* source.fetch(1024, 20) // read 20 bytes at offset 1024
|
|
26
|
+
* source.fetch(-1024) // load the last 1024 bytes
|
|
27
|
+
*```
|
|
28
|
+
* @param offset Byte to start reading form
|
|
29
|
+
* @param length optional number of bytes to read
|
|
30
|
+
*/
|
|
31
|
+
fetch(offset: number, length?: number): Promise<ArrayBuffer>;
|
|
32
|
+
}
|
|
33
|
+
/** Metadata returned from some sources like HTTP or AWS */
|
|
34
|
+
export interface SourceMetadata {
|
|
35
|
+
/** number of bytes of the file */
|
|
36
|
+
size?: number;
|
|
37
|
+
/** Entity tag */
|
|
38
|
+
eTag?: string;
|
|
39
|
+
contentType?: string;
|
|
40
|
+
contentDisposition?: string;
|
|
41
|
+
lastModified?: string;
|
|
42
|
+
metadata?: Record<string, unknown>;
|
|
43
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source.js","sourceRoot":"","sources":["../../src/source.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { SourceCallback, SourceMiddleware } from './middleware.js';
|
|
2
|
+
import { Source, SourceMetadata } from './source.js';
|
|
3
|
+
/**
|
|
4
|
+
* Wrap a source with middleware to modify requests to the sources
|
|
5
|
+
*
|
|
6
|
+
* @see @chunkd/middleware
|
|
7
|
+
*/
|
|
8
|
+
export declare class SourceView implements Source {
|
|
9
|
+
source: Source;
|
|
10
|
+
middleware: SourceMiddleware[];
|
|
11
|
+
static is(s: Source): s is SourceView;
|
|
12
|
+
constructor(source: Source, middleware?: SourceMiddleware[]);
|
|
13
|
+
get type(): string;
|
|
14
|
+
get url(): URL;
|
|
15
|
+
get metadata(): SourceMetadata | undefined;
|
|
16
|
+
head(): Promise<SourceMetadata>;
|
|
17
|
+
close(): Promise<void>;
|
|
18
|
+
fetch(offset: number, length?: number): Promise<ArrayBuffer>;
|
|
19
|
+
/** Run a request using all the middleware */
|
|
20
|
+
run(handler: SourceCallback, offset: number, length?: number): Promise<ArrayBuffer>;
|
|
21
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wrap a source with middleware to modify requests to the sources
|
|
3
|
+
*
|
|
4
|
+
* @see @chunkd/middleware
|
|
5
|
+
*/
|
|
6
|
+
export class SourceView {
|
|
7
|
+
source;
|
|
8
|
+
middleware;
|
|
9
|
+
static is(s) {
|
|
10
|
+
if ('middleware' in s)
|
|
11
|
+
return true;
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
constructor(source, middleware = []) {
|
|
15
|
+
this.source = source;
|
|
16
|
+
this.middleware = middleware;
|
|
17
|
+
}
|
|
18
|
+
get type() {
|
|
19
|
+
return this.source.type;
|
|
20
|
+
}
|
|
21
|
+
get url() {
|
|
22
|
+
return this.source.url;
|
|
23
|
+
}
|
|
24
|
+
get metadata() {
|
|
25
|
+
return this.source.metadata;
|
|
26
|
+
}
|
|
27
|
+
head() {
|
|
28
|
+
return this.source.head();
|
|
29
|
+
}
|
|
30
|
+
async close() {
|
|
31
|
+
return this.source.close?.();
|
|
32
|
+
}
|
|
33
|
+
async fetch(offset, length) {
|
|
34
|
+
const middleware = this.middleware;
|
|
35
|
+
if (middleware == null || middleware.length === 0)
|
|
36
|
+
return this.source.fetch(offset, length);
|
|
37
|
+
const handler = (req) => this.source.fetch(req.offset, req.length);
|
|
38
|
+
return this.run(handler, offset, length);
|
|
39
|
+
}
|
|
40
|
+
/** Run a request using all the middleware */
|
|
41
|
+
async run(handler, offset, length) {
|
|
42
|
+
const middleware = this.middleware;
|
|
43
|
+
if (middleware == null)
|
|
44
|
+
return handler({ source: this, offset, length });
|
|
45
|
+
function runMiddleware(middleware, next) {
|
|
46
|
+
return (req) => middleware.fetch(req, next);
|
|
47
|
+
}
|
|
48
|
+
for (let i = middleware.length - 1; i >= 0; i--)
|
|
49
|
+
handler = runMiddleware(middleware[i], handler);
|
|
50
|
+
return handler({ source: this, offset, length });
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=view.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"view.js","sourceRoot":"","sources":["../../src/view.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,MAAM,OAAO,UAAU;IACrB,MAAM,CAAS;IACf,UAAU,CAAqB;IAE/B,MAAM,CAAC,EAAE,CAAC,CAAS;QACjB,IAAI,YAAY,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QACnC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,YAAY,MAAc,EAAE,aAAiC,EAAE;QAC7D,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;IAC1B,CAAC;IAED,IAAI,GAAG;QACL,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;IACzB,CAAC;IAED,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;IAC9B,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,KAAK;QACT,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,MAAc,EAAE,MAAe;QACzC,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;QACnC,IAAI,UAAU,IAAI,IAAI,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC5F,MAAM,OAAO,GAAmB,CAAC,GAAkB,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QAClG,OAAO,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3C,CAAC;IAED,6CAA6C;IAC7C,KAAK,CAAC,GAAG,CAAC,OAAuB,EAAE,MAAc,EAAE,MAAe;QAChE,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;QACnC,IAAI,UAAU,IAAI,IAAI;YAAE,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QAEzE,SAAS,aAAa,CAAC,UAA4B,EAAE,IAAoB;YACvE,OAAO,CAAC,GAAkB,EAAwB,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACnF,CAAC;QAED,KAAK,IAAI,CAAC,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE;YAAE,OAAO,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QACjG,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACnD,CAAC;CACF"}
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@chunkd/source",
|
|
3
|
+
"version": "11.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"engines": {
|
|
6
|
+
"node": ">=16.0.0"
|
|
7
|
+
},
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/blacha/chunkd.git",
|
|
11
|
+
"directory": "packages/source"
|
|
12
|
+
},
|
|
13
|
+
"main": "./build/src/index.js",
|
|
14
|
+
"types": "./build/src/index.d.ts",
|
|
15
|
+
"author": "Blayne Chard",
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"scripts": {
|
|
18
|
+
"test": "node --test"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@types/node": "^18.0.0"
|
|
22
|
+
},
|
|
23
|
+
"publishConfig": {
|
|
24
|
+
"access": "public"
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"build/src"
|
|
28
|
+
],
|
|
29
|
+
"gitHead": "b8136f070ded8ec3649c6cdf729e69b40ceec324"
|
|
30
|
+
}
|