@eltjs/elt 0.1.3 → 0.3.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/README.md +3 -3
- package/dist/core/copy.d.ts +3 -1
- package/dist/core/copy.js +4 -3
- package/dist/core/derived-dataset.d.ts +7 -0
- package/dist/core/derived-dataset.js +14 -0
- package/dist/core/derived-refreshes.d.ts +3 -2
- package/dist/core/derived-refreshes.js +20 -8
- package/dist/core/destination.d.ts +3 -2
- package/dist/core/destination.js +2 -2
- package/dist/core/pipeline.js +12 -5
- package/dist/core/replication.js +7 -4
- package/dist/core/writer.d.ts +7 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -718,7 +718,7 @@ When a change signal fails:
|
|
|
718
718
|
|
|
719
719
|
- A failed change signal fails only its streams. The other streams of the connection continue to load. A failed stream is not current as of the check.
|
|
720
720
|
- The sync history records the failure one time, when the change signal starts to fail, as a failed pass of its streams with the failure type of the error.
|
|
721
|
-
- After a `system` failure, such as a connection that its upstream dropped, the next check reads the gauge again, as Prometheus scrapes a failed target again at its next interval.
|
|
721
|
+
- After a `system` failure, such as a connection that its upstream dropped, the next check reads the gauge again, as Prometheus scrapes a failed target again at its next interval. The first check that reads the gauge loads its streams again, also when the value did not change. Thus the sync history has a pass after the failed one, and a stream that failed for one check does not show as failed until its next change.
|
|
722
722
|
- After a `config` failure, the watch reads that gauge no more, and its streams stay failed, because only the user can fix it. A new watch reads the gauge again.
|
|
723
723
|
- An upkeep that fails is recorded in the same way, as a failed pass of the streams of the connection. After a `system` failure it runs again at its next interval. After a `config` failure it runs no more in this watch.
|
|
724
724
|
- Change signals that break the contract stop their connection: a change signal names a stream that the connection did not select, a selected stream is in no change signal, the change signals of one stream have two intervals or two timeouts, or an interval or a timeout is not a positive number of milliseconds. A `changeSignals()` that throws also stops its connection. The sync history records it as a failed attempt. The other connections continue.
|
|
@@ -826,7 +826,7 @@ The destination contract:
|
|
|
826
826
|
|
|
827
827
|
- Declarations are frozen, and you can use them again.
|
|
828
828
|
- `Destination.createWriter(configuration, target)` selects a strategy of the storage with no I/O.
|
|
829
|
-
- `Destination.load()` opens the one hold of the pass on the storage.
|
|
829
|
+
- `Destination.load({ clock, connection })` opens the one hold of the pass on the storage. `connection` is the name of the connection whose pass opens it, so a destination that records its loads can name each one.
|
|
830
830
|
- `load.prepare(configuration, target, { writer, reloading })` gives each stream its `Stage`. A `Stage` has `apply`, `commit` and `discard`. It also has `fresh`, which is true when the target holds none of the earlier rows of the copy, so the copy reads from no checkpoint; `reloading`, which is true while commits go to a hidden target; and `complete`, which puts that hidden target in the place of the target after the stream ends with no failure.
|
|
831
831
|
- Each destination uses `reloadMode` to decide what to do with the target: load into it, make it, evolve a stored target that the stream does not fit now ([shape changes](#shape-changes)), open a reload for an overwrite whose stored target does not fit now, or continue the reload that the last run of the copy left open. A `RESET` of the full stream also opens a reload.
|
|
832
832
|
- Destinations own connections, files and publication. `Copy` and `Pipeline` have no SQL or file system code of a load.
|
|
@@ -1058,7 +1058,7 @@ Two rules exist:
|
|
|
1058
1058
|
## When a derived dataset fails
|
|
1059
1059
|
|
|
1060
1060
|
- **A rule failure** is the output of its input: the status `failed` and the reason. The load and the run continue, and the next refresh tries the input again. See [ADR 0004](./docs/adr/0004-a-rule-failure-stays-on-its-output.md).
|
|
1061
|
-
- **A dataset failure**, for example SQL that SQLite refuses, rejects the run
|
|
1061
|
+
- **A dataset failure**, for example SQL that SQLite refuses, rejects the run, or it stops the watch, with a `DerivedDatasetError`. Its `dataset` names the dataset, and its `cause` is the error of the store. The passes that a stopped watch ended are `cancelled` in the sync history, and their records do not name the failure.
|
|
1062
1062
|
- **A copy that failed** keeps its last committed rows. The derived data of those rows stays as it was.
|
|
1063
1063
|
|
|
1064
1064
|
## The same concepts in other systems
|
package/dist/core/copy.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { CheckpointStore } from '../state/checkpoint-store.ts';
|
|
2
|
+
import type { PipelineClock } from './clock.ts';
|
|
3
|
+
import type { Connection } from './connection.ts';
|
|
2
4
|
import { CopyConfiguration } from './copy-configuration.ts';
|
|
3
5
|
import type { Destination } from './destination.ts';
|
|
4
6
|
import type { Source } from './source.ts';
|
|
@@ -23,5 +25,5 @@ export declare class Copy<Target extends DestinationTarget> {
|
|
|
23
25
|
get from(): Stream;
|
|
24
26
|
writer(source: Source): string;
|
|
25
27
|
validate(source: Source, destination: Destination<Target>, checkpoints?: CheckpointStore): void;
|
|
26
|
-
clear(source
|
|
28
|
+
clear({ name, source, destination, checkpoints }: Connection<Target>, clock: PipelineClock): Promise<void>;
|
|
27
29
|
}
|
package/dist/core/copy.js
CHANGED
|
@@ -44,10 +44,11 @@ export class Copy {
|
|
|
44
44
|
}
|
|
45
45
|
// Empties the target and removes this copy's checkpoint together, so the
|
|
46
46
|
// next run reloads from scratch.
|
|
47
|
-
async clear(source, destination, checkpoints) {
|
|
47
|
+
async clear({ name, source, destination, checkpoints }, clock) {
|
|
48
48
|
this.validate(source, destination, checkpoints);
|
|
49
|
-
const
|
|
50
|
-
const
|
|
49
|
+
const writer = this.writer(source);
|
|
50
|
+
const files = new FileTransfer(this.configuration.fileReads, destination.location(this.to), writer);
|
|
51
|
+
const drop = () => destination.clear(this.configuration, this.to, { writer, clock, connection: name }, (values) => files.reconcile(values));
|
|
51
52
|
if (this.id !== undefined && checkpoints !== undefined)
|
|
52
53
|
await checkpoints.clear(this.id, drop);
|
|
53
54
|
else
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { PipelineClock } from './clock.ts';
|
|
1
2
|
import type { Connection } from './connection.ts';
|
|
2
3
|
import type { Target as DestinationTarget } from './target.ts';
|
|
3
4
|
export type RefreshTrigger = {
|
|
@@ -7,11 +8,17 @@ export type RefreshTrigger = {
|
|
|
7
8
|
readonly kind: 'pass';
|
|
8
9
|
readonly tried: ReadonlySet<string>;
|
|
9
10
|
};
|
|
11
|
+
export declare class DerivedDatasetError extends Error {
|
|
12
|
+
name: string;
|
|
13
|
+
readonly dataset: string;
|
|
14
|
+
constructor(dataset: string, cause: unknown);
|
|
15
|
+
}
|
|
10
16
|
export declare abstract class DerivedDataset<Target extends DestinationTarget> {
|
|
11
17
|
abstract readonly name: string;
|
|
12
18
|
validate(_connections: readonly Connection<Target>[]): void;
|
|
13
19
|
abstract refresh(options: {
|
|
14
20
|
readonly connections: readonly Connection<Target>[];
|
|
21
|
+
readonly clock: PipelineClock;
|
|
15
22
|
readonly earlier: readonly DerivedDataset<Target>[];
|
|
16
23
|
readonly signal?: AbortSignal;
|
|
17
24
|
readonly trigger: RefreshTrigger;
|
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
import { errorMessage } from '../state/sync-history.js';
|
|
2
|
+
// A dataset's own failure, such as SQL its store refuses, named for whoever
|
|
3
|
+
// reads it in a log: the cause alone, such as "no such column: x", does not say
|
|
4
|
+
// which dataset of the pipeline failed.
|
|
5
|
+
export class DerivedDatasetError extends Error {
|
|
6
|
+
name = 'DerivedDatasetError';
|
|
7
|
+
dataset;
|
|
8
|
+
constructor(dataset, cause) {
|
|
9
|
+
super(`Derived dataset ${dataset} failed: ${errorMessage(cause)}`, {
|
|
10
|
+
cause,
|
|
11
|
+
});
|
|
12
|
+
this.dataset = dataset;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
1
15
|
// Data a pipeline keeps in step with what its copies load, and can always
|
|
2
16
|
// rebuild from it (Kleppmann's derived data; Estuary's derivations), such as a
|
|
3
17
|
// view over loaded tables or the text of the files a copy stored. Each kind
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import type { PipelineClock } from './clock.ts';
|
|
1
2
|
import type { Connection } from './connection.ts';
|
|
2
|
-
import type
|
|
3
|
+
import { type DerivedDataset, type RefreshTrigger } from './derived-dataset.ts';
|
|
3
4
|
import type { Target as DestinationTarget } from './target.ts';
|
|
4
5
|
type Kind = RefreshTrigger['kind'];
|
|
5
6
|
export declare class DerivedRefreshes<Target extends DestinationTarget> {
|
|
6
7
|
#private;
|
|
7
|
-
constructor(datasets: readonly DerivedDataset<Target>[], connections: readonly Connection<Target>[], signal: AbortSignal | undefined, stop: (
|
|
8
|
+
constructor(datasets: readonly DerivedDataset<Target>[], connections: readonly Connection<Target>[], clock: PipelineClock, signal: AbortSignal | undefined, stop: () => void);
|
|
8
9
|
get failure(): {
|
|
9
10
|
readonly error: unknown;
|
|
10
11
|
} | undefined;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Latch } from '@zukhruf/async';
|
|
2
|
+
import { DerivedDatasetError, } from './derived-dataset.js';
|
|
2
3
|
// No refresh runs.
|
|
3
4
|
class Idle {
|
|
4
5
|
}
|
|
@@ -39,6 +40,7 @@ class Failed {
|
|
|
39
40
|
export class DerivedRefreshes {
|
|
40
41
|
#datasets;
|
|
41
42
|
#connections;
|
|
43
|
+
#clock;
|
|
42
44
|
#signal;
|
|
43
45
|
#stop;
|
|
44
46
|
#state = new Idle();
|
|
@@ -46,9 +48,10 @@ export class DerivedRefreshes {
|
|
|
46
48
|
// refresh; the memory of the passes that run, which ends with them.
|
|
47
49
|
#tried = new Map();
|
|
48
50
|
#health = new Healthy();
|
|
49
|
-
constructor(datasets, connections, signal, stop) {
|
|
51
|
+
constructor(datasets, connections, clock, signal, stop) {
|
|
50
52
|
this.#datasets = datasets;
|
|
51
53
|
this.#connections = connections;
|
|
54
|
+
this.#clock = clock;
|
|
52
55
|
this.#signal = signal;
|
|
53
56
|
this.#stop = stop;
|
|
54
57
|
}
|
|
@@ -84,12 +87,21 @@ export class DerivedRefreshes {
|
|
|
84
87
|
for (const [index, dataset] of this.#datasets.entries()) {
|
|
85
88
|
const tried = this.#tried.get(dataset) ?? new Set();
|
|
86
89
|
this.#tried.set(dataset, tried);
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
90
|
+
try {
|
|
91
|
+
await dataset.refresh({
|
|
92
|
+
connections: this.#connections,
|
|
93
|
+
clock: this.#clock,
|
|
94
|
+
earlier: this.#datasets.slice(0, index),
|
|
95
|
+
signal: this.#signal,
|
|
96
|
+
trigger: { kind, tried },
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
// A stop is not the dataset's failure.
|
|
101
|
+
if (this.#signal?.aborted === true)
|
|
102
|
+
throw error;
|
|
103
|
+
throw new DerivedDatasetError(dataset.name, error);
|
|
104
|
+
}
|
|
93
105
|
}
|
|
94
106
|
// The passes it follows ended, and their memory with them.
|
|
95
107
|
if (kind === 'pass')
|
|
@@ -109,7 +121,7 @@ export class DerivedRefreshes {
|
|
|
109
121
|
catch (error) {
|
|
110
122
|
if (this.#signal?.aborted !== true) {
|
|
111
123
|
this.#health = new Failed(error);
|
|
112
|
-
this.#stop(
|
|
124
|
+
this.#stop();
|
|
113
125
|
}
|
|
114
126
|
}
|
|
115
127
|
finally {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { PipelineClock } from './clock.ts';
|
|
2
2
|
import type { CopyConfiguration } from './copy-configuration.ts';
|
|
3
3
|
import type { Target as DestinationTarget } from './target.ts';
|
|
4
|
-
import type { FieldValues, Stage, Writer } from './writer.ts';
|
|
4
|
+
import type { Clearing, FieldValues, Stage, Writer } from './writer.ts';
|
|
5
5
|
export type DestinationSyncMode = 'append' | 'overwrite' | 'append_dedup' | 'overwrite_dedup';
|
|
6
6
|
export type Load<Target extends DestinationTarget> = AsyncDisposable & {
|
|
7
7
|
prepare(configuration: CopyConfiguration, target: Target, binding: {
|
|
@@ -17,6 +17,7 @@ export declare abstract class Destination<Target extends DestinationTarget> {
|
|
|
17
17
|
abstract createWriter(configuration: CopyConfiguration, target: Target): Writer;
|
|
18
18
|
abstract load(options: {
|
|
19
19
|
clock: PipelineClock;
|
|
20
|
+
connection: string;
|
|
20
21
|
}): Promise<Load<Target>>;
|
|
21
|
-
clear(configuration: CopyConfiguration, target: Target,
|
|
22
|
+
clear(configuration: CopyConfiguration, target: Target, clearing: Clearing, committed?: (values: FieldValues) => Promise<void>): Promise<void>;
|
|
22
23
|
}
|
package/dist/core/destination.js
CHANGED
|
@@ -11,7 +11,7 @@ export class Destination {
|
|
|
11
11
|
if (!this.supportedDestinationSyncModes.includes(configuration.destinationSyncMode))
|
|
12
12
|
throw new TypeError(`Destination does not support ${configuration.destinationSyncMode}`);
|
|
13
13
|
}
|
|
14
|
-
async clear(configuration, target,
|
|
15
|
-
await this.createWriter(configuration, target).clear(
|
|
14
|
+
async clear(configuration, target, clearing, committed) {
|
|
15
|
+
await this.createWriter(configuration, target).clear(clearing, committed);
|
|
16
16
|
}
|
|
17
17
|
}
|
package/dist/core/pipeline.js
CHANGED
|
@@ -72,7 +72,7 @@ export class Pipeline {
|
|
|
72
72
|
const connection = this.connections.find(({ steps }) => steps.includes(copy));
|
|
73
73
|
if (connection === undefined)
|
|
74
74
|
throw new TypeError("Only this pipeline's copies can be cleared");
|
|
75
|
-
await copy.clear(connection
|
|
75
|
+
await copy.clear(connection, this.#clock);
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
// Once signal aborts, each pass stops at its next message and is recorded as
|
|
@@ -87,7 +87,7 @@ export class Pipeline {
|
|
|
87
87
|
async run(options) {
|
|
88
88
|
const signal = options?.signal;
|
|
89
89
|
await this.#declare();
|
|
90
|
-
const refreshes = new DerivedRefreshes(this.derived, this.connections, signal, () => { });
|
|
90
|
+
const refreshes = new DerivedRefreshes(this.derived, this.connections, this.#clock, signal, () => { });
|
|
91
91
|
let passes;
|
|
92
92
|
try {
|
|
93
93
|
passes = await Promise.allSettled(this.connections.map((connection) => this.#pass(connection, connection.steps, signal, () => refreshes.request('commit'))));
|
|
@@ -128,7 +128,10 @@ export class Pipeline {
|
|
|
128
128
|
const controller = new AbortController();
|
|
129
129
|
const watching = AbortSignal.any([signal, controller.signal]);
|
|
130
130
|
const stopped = [];
|
|
131
|
-
const refreshes = new DerivedRefreshes(this.derived, this.connections, watching,
|
|
131
|
+
const refreshes = new DerivedRefreshes(this.derived, this.connections, this.#clock, watching,
|
|
132
|
+
// With no reason: the passes it stops were not refused by this failure,
|
|
133
|
+
// and no sync history records a dataset's failure (ADR 0004).
|
|
134
|
+
() => controller.abort());
|
|
132
135
|
const passes = interleave(this.connections
|
|
133
136
|
.filter(({ steps }) => steps.length > 0)
|
|
134
137
|
.map((connection) => this.#watch(connection, watching, controller, stopped, () => refreshes.request('commit'))), Number.POSITIVE_INFINITY);
|
|
@@ -275,8 +278,12 @@ export class Pipeline {
|
|
|
275
278
|
}
|
|
276
279
|
continue;
|
|
277
280
|
}
|
|
278
|
-
|
|
279
|
-
|
|
281
|
+
// A stream whose change signal failed loads again when a check
|
|
282
|
+
// reads the signal again, also with no new value: the history
|
|
283
|
+
// shows the latest attempt of a stream, and only a pass follows
|
|
284
|
+
// the failed one (ADR 0020).
|
|
285
|
+
const recovered = failing.delete(name);
|
|
286
|
+
if (outcome.state === 'changed' || recovered) {
|
|
280
287
|
unchangedAt.delete(name);
|
|
281
288
|
pending.add(name);
|
|
282
289
|
}
|
package/dist/core/replication.js
CHANGED
|
@@ -99,9 +99,9 @@ export async function replicate(source, destination, checkpoints, copies, connec
|
|
|
99
99
|
});
|
|
100
100
|
try {
|
|
101
101
|
if (checkpoints === undefined || bindings.size === 0)
|
|
102
|
-
await transfer(source, destination, null, replications, signal, clock);
|
|
102
|
+
await transfer(source, destination, connection, null, replications, signal, clock);
|
|
103
103
|
else
|
|
104
|
-
await checkpoints.run(bindings, (run) => transfer(source, destination, run, replications, signal, clock));
|
|
104
|
+
await checkpoints.run(bindings, (run) => transfer(source, destination, connection, run, replications, signal, clock));
|
|
105
105
|
}
|
|
106
106
|
catch (error) {
|
|
107
107
|
for (const replication of replications)
|
|
@@ -115,7 +115,7 @@ export async function replicate(source, destination, checkpoints, copies, connec
|
|
|
115
115
|
replication.settle();
|
|
116
116
|
return replications.map((replication) => replication.outcome());
|
|
117
117
|
}
|
|
118
|
-
async function transfer(source, destination, run, replications, signal, clock) {
|
|
118
|
+
async function transfer(source, destination, connection, run, replications, signal, clock) {
|
|
119
119
|
const byStream = new Map(replications.map((replication) => [replication.stream.name, replication]));
|
|
120
120
|
const incremental = (replication) => replication.copy.configuration.syncMode === 'incremental';
|
|
121
121
|
const checkpoint = (replication) => {
|
|
@@ -153,7 +153,10 @@ async function transfer(source, destination, run, replications, signal, clock) {
|
|
|
153
153
|
if (reading.length === 0)
|
|
154
154
|
return;
|
|
155
155
|
signal?.throwIfAborted();
|
|
156
|
-
await using load = await destination.load({
|
|
156
|
+
await using load = await destination.load({
|
|
157
|
+
clock,
|
|
158
|
+
connection: connection.name,
|
|
159
|
+
});
|
|
157
160
|
// Every target is prepared before anything is read; a copy whose target is
|
|
158
161
|
// refused reads nothing.
|
|
159
162
|
const prepared = [];
|
package/dist/core/writer.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { PipelineClock } from './clock.ts';
|
|
1
2
|
import type { Partition } from './partition.ts';
|
|
2
3
|
import type { FailureType, KeyValue } from './source.ts';
|
|
3
4
|
import type { Stream } from './stream.ts';
|
|
@@ -37,5 +38,10 @@ export type Stage = AsyncDisposable & {
|
|
|
37
38
|
export declare abstract class Writer {
|
|
38
39
|
readonly stream: Stream;
|
|
39
40
|
constructor(stream: Stream);
|
|
40
|
-
abstract clear(
|
|
41
|
+
abstract clear(clearing: Clearing, committed?: (values: FieldValues) => Promise<void>): Promise<void>;
|
|
41
42
|
}
|
|
43
|
+
export type Clearing = {
|
|
44
|
+
readonly writer: string;
|
|
45
|
+
readonly clock: PipelineClock;
|
|
46
|
+
readonly connection: string;
|
|
47
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export { Copy, type CopyOutcome, type CopyResult } from './core/copy.ts';
|
|
|
5
5
|
export { CopyConfiguration, type DedupPolicy, } from './core/copy-configuration.ts';
|
|
6
6
|
export type { Deduplication } from './core/deduplication.ts';
|
|
7
7
|
export { Destination, type DestinationSyncMode, type Load, } from './core/destination.ts';
|
|
8
|
-
export { DerivedDataset, type RefreshTrigger } from './core/derived-dataset.ts';
|
|
8
|
+
export { DerivedDataset, DerivedDatasetError, type RefreshTrigger, } from './core/derived-dataset.ts';
|
|
9
9
|
export { DocumentParser } from './core/document-parser.ts';
|
|
10
10
|
export { DocumentText } from './core/document-text.ts';
|
|
11
11
|
export { type LoadedRow, Rule, type RuleColumn, type RuleResult, } from './core/rule.ts';
|
|
@@ -33,7 +33,7 @@ export { type Upkeep } from './core/upkeep.ts';
|
|
|
33
33
|
export { Stream, type SyncMode } from './core/stream.ts';
|
|
34
34
|
export { Target } from './core/target.ts';
|
|
35
35
|
export { type DescribedColumn, describeTarget, type TargetDescription, } from './core/target-description.ts';
|
|
36
|
-
export { type FieldValues, type LoadFailure, type Stage, TargetOwnedError, type WriteCount, type WriteOperation, Writer, } from './core/writer.ts';
|
|
36
|
+
export { type Clearing, type FieldValues, type LoadFailure, type Stage, TargetOwnedError, type WriteCount, type WriteOperation, Writer, } from './core/writer.ts';
|
|
37
37
|
export { type CheckpointBinding, type CheckpointRun, type CheckpointSession, CheckpointStore, type StoredCheckpoint, } from './state/checkpoint-store.ts';
|
|
38
38
|
export { copyStatus, type DeclaredCopy, errorMessage, passError, passFailureType, passStatus, type RecordedPass, recordedFailure, type StreamCheck, SyncHistory, type SyncStatus, } from './state/sync-history.ts';
|
|
39
39
|
export { syncHistoryRelations } from './state/sync-history-relations.ts';
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ export { Connection } from './core/connection.js';
|
|
|
3
3
|
export { Copy } from './core/copy.js';
|
|
4
4
|
export { CopyConfiguration, } from './core/copy-configuration.js';
|
|
5
5
|
export { Destination, } from './core/destination.js';
|
|
6
|
-
export { DerivedDataset } from './core/derived-dataset.js';
|
|
6
|
+
export { DerivedDataset, DerivedDatasetError, } from './core/derived-dataset.js';
|
|
7
7
|
export { DocumentParser } from './core/document-parser.js';
|
|
8
8
|
export { DocumentText } from './core/document-text.js';
|
|
9
9
|
export { Rule, } from './core/rule.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eltjs/elt",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "A pipeline that copies the data of apps and services into stores that SQL can read: sources, streams, checkpoints, watches and derived datasets.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|