@deterministic-code/datasources-json 0.0.0-stage → 0.1.3
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/dist/JsonDriver.d.ts +8 -0
- package/dist/JsonDriver.js +10 -0
- package/dist/command.d.ts +14 -0
- package/dist/command.js +103 -0
- package/dist/connection-options.d.ts +7 -0
- package/dist/connection-options.js +1 -0
- package/dist/connection.d.ts +28 -0
- package/dist/connection.js +92 -0
- package/dist/file-store.d.ts +3 -0
- package/dist/file-store.js +2 -0
- package/dist/filter.d.ts +7 -0
- package/dist/filter.js +29 -0
- package/dist/i-file-store.d.ts +10 -0
- package/dist/i-file-store.js +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/memory-file-store.d.ts +8 -0
- package/dist/memory-file-store.js +18 -0
- package/dist/node-file-store.d.ts +8 -0
- package/dist/node-file-store.js +27 -0
- package/dist/transaction.d.ts +9 -0
- package/dist/transaction.js +18 -0
- package/package.json +21 -4
- package/README.md +0 -3
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type Cell, type DatasourceOptions, type ICommand, type IConnection, type IDriver, type ITransaction, type IsolationLevel, type TypeConverter } from "@deterministic-code/datasources";
|
|
2
|
+
export declare class JsonDriver implements IDriver {
|
|
3
|
+
rowTypeConverters: Record<string, TypeConverter<Cell, Cell>>;
|
|
4
|
+
columnType: (name: string) => string;
|
|
5
|
+
connection: (options?: DatasourceOptions) => IConnection;
|
|
6
|
+
command: (connection: IConnection) => ICommand;
|
|
7
|
+
transaction: (connection: IConnection, isolation?: IsolationLevel) => ITransaction;
|
|
8
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { columnType as identityColumnType, } from "@deterministic-code/datasources";
|
|
2
|
+
import { JsonConnection } from "./connection.js";
|
|
3
|
+
import { JsonTransaction } from "./transaction.js";
|
|
4
|
+
export class JsonDriver {
|
|
5
|
+
rowTypeConverters = {};
|
|
6
|
+
columnType = identityColumnType;
|
|
7
|
+
connection = (options) => JsonConnection.from(options);
|
|
8
|
+
command = (connection) => connection.createCommand();
|
|
9
|
+
transaction = (connection, isolation = "readCommitted") => new JsonTransaction(connection, isolation);
|
|
10
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { CommandMiddlewareHost, Native, type Cells, type ICommand, type IReader, type IStatement, Response, type Parameter } from "@deterministic-code/datasources";
|
|
2
|
+
import type { JsonConnection } from "./connection.js";
|
|
3
|
+
export declare class JsonCommand extends CommandMiddlewareHost implements ICommand {
|
|
4
|
+
readonly connection: JsonConnection;
|
|
5
|
+
constructor(connection: JsonConnection);
|
|
6
|
+
executeReaderNative(text: Native, parameters?: Parameter[]): Promise<IReader<Cells>>;
|
|
7
|
+
executeNative(text: Native, parameters?: Parameter[]): Promise<Response>;
|
|
8
|
+
executeReader(text: string, parameters?: Parameter[]): Promise<IReader<Cells>>;
|
|
9
|
+
executeReaderStatement: (statement: IStatement, parameters?: Parameter[]) => Promise<IReader<Cells>>;
|
|
10
|
+
executeStatement: (statement: IStatement, parameters?: Parameter[]) => Promise<Response>;
|
|
11
|
+
execute(text: string, parameters?: Parameter[]): Promise<Response>;
|
|
12
|
+
private applyUpdate;
|
|
13
|
+
private applyDelete;
|
|
14
|
+
}
|
package/dist/command.js
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { ArrayReader, CommandMiddlewareHost, DeleteStatement, DefaultStatementTextRenderer, InsertStatement, SelectInsertedIdStatement, UpdateStatement, Response, } from "@deterministic-code/datasources";
|
|
2
|
+
import { asRecord, matches, parametersToObject, parseFilter, } from "./filter.js";
|
|
3
|
+
export class JsonCommand extends CommandMiddlewareHost {
|
|
4
|
+
connection;
|
|
5
|
+
constructor(connection) {
|
|
6
|
+
super();
|
|
7
|
+
this.connection = connection;
|
|
8
|
+
}
|
|
9
|
+
executeReaderNative(text, parameters) {
|
|
10
|
+
return this.executeReader(text.text, parameters);
|
|
11
|
+
}
|
|
12
|
+
executeNative(text, parameters) {
|
|
13
|
+
return this.execute(text.text, parameters);
|
|
14
|
+
}
|
|
15
|
+
async executeReader(text, parameters) {
|
|
16
|
+
return this.run(text, parameters, async (query, params) => {
|
|
17
|
+
this.connection.ensureOpen();
|
|
18
|
+
const filter = {
|
|
19
|
+
...parseFilter(query),
|
|
20
|
+
...parametersToObject(params),
|
|
21
|
+
};
|
|
22
|
+
const rows = this.connection
|
|
23
|
+
.getCollection()
|
|
24
|
+
.filter((row) => matches(asRecord(row), filter));
|
|
25
|
+
const cells = rows.map(asRecord);
|
|
26
|
+
return { value: new ArrayReader(cells), rows: cells };
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
executeReaderStatement = (statement, parameters) => statement instanceof SelectInsertedIdStatement
|
|
30
|
+
? this.run(`${statement.table}.${statement.column}`, parameters, async () => {
|
|
31
|
+
this.connection.ensureOpen();
|
|
32
|
+
return { value: new ArrayReader([]), rows: [] };
|
|
33
|
+
})
|
|
34
|
+
: this.executeReader(filterText(statement), parameters);
|
|
35
|
+
executeStatement = (statement, parameters) => statement instanceof InsertStatement
|
|
36
|
+
? this.execute("insert", parameters)
|
|
37
|
+
: statement instanceof UpdateStatement
|
|
38
|
+
? this.execute("update", withWhere(parameters, statement.where))
|
|
39
|
+
: statement instanceof DeleteStatement
|
|
40
|
+
? this.execute("delete", withWhere(parameters, statement.where))
|
|
41
|
+
: this.execute(DefaultStatementTextRenderer.instance.render(statement), parameters);
|
|
42
|
+
async execute(text, parameters) {
|
|
43
|
+
if (!text.trim())
|
|
44
|
+
throw new Error("empty command");
|
|
45
|
+
return this.run(text, parameters, async (query, params) => {
|
|
46
|
+
this.connection.ensureOpen();
|
|
47
|
+
const op = query.trim().toLowerCase();
|
|
48
|
+
const obj = parametersToObject(params);
|
|
49
|
+
if (op === "insert") {
|
|
50
|
+
this.connection.getCollection().push(obj);
|
|
51
|
+
await this.connection.persist();
|
|
52
|
+
return { value: new Response(obj, 1, params), rows: [] };
|
|
53
|
+
}
|
|
54
|
+
if (op === "update") {
|
|
55
|
+
const whereText = typeof obj.$where === "string" ? obj.$where : undefined;
|
|
56
|
+
const next = { ...obj };
|
|
57
|
+
delete next.$where;
|
|
58
|
+
const filter = whereText ? parseFilter(whereText) : next;
|
|
59
|
+
const updated = await this.applyUpdate(next, filter);
|
|
60
|
+
return { value: new Response(updated.result, updated.rowsAffected, params), rows: [] };
|
|
61
|
+
}
|
|
62
|
+
if (op === "delete") {
|
|
63
|
+
const filter = obj;
|
|
64
|
+
const deleted = await this.applyDelete(filter);
|
|
65
|
+
return { value: new Response(deleted.result, deleted.rowsAffected, params), rows: [] };
|
|
66
|
+
}
|
|
67
|
+
throw new Error(`Unsupported JSON command: ${query}`);
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
async applyUpdate(obj, filter) {
|
|
71
|
+
const collection = this.connection.getCollection();
|
|
72
|
+
let rowsAffected = 0;
|
|
73
|
+
for (let i = 0; i < collection.length; i += 1) {
|
|
74
|
+
if (matches(asRecord(collection[i]), filter)) {
|
|
75
|
+
collection[i] = { ...asRecord(collection[i]), ...obj };
|
|
76
|
+
rowsAffected += 1;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
await this.connection.persist();
|
|
80
|
+
return { result: obj, rowsAffected };
|
|
81
|
+
}
|
|
82
|
+
async applyDelete(filter) {
|
|
83
|
+
const collection = this.connection.getCollection();
|
|
84
|
+
const remaining = collection.filter((row) => !matches(asRecord(row), filter));
|
|
85
|
+
const rowsAffected = collection.length - remaining.length;
|
|
86
|
+
collection.length = 0;
|
|
87
|
+
collection.push(...remaining);
|
|
88
|
+
await this.connection.persist();
|
|
89
|
+
return { result: undefined, rowsAffected };
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
const looksJson = (text) => !!text?.trimStart().startsWith("{");
|
|
93
|
+
const renderWhere = (where) => where ? DefaultStatementTextRenderer.instance.render(where) : undefined;
|
|
94
|
+
const filterText = (statement) => {
|
|
95
|
+
const where = "where" in statement ? renderWhere(statement.where) : undefined;
|
|
96
|
+
if (looksJson(where))
|
|
97
|
+
return where;
|
|
98
|
+
const text = DefaultStatementTextRenderer.instance.render(statement);
|
|
99
|
+
return looksJson(text) || !text.trim() ? text : "";
|
|
100
|
+
};
|
|
101
|
+
const withWhere = (parameters, where) => looksJson(renderWhere(where))
|
|
102
|
+
? [...(parameters ?? []), { name: "$where", value: renderWhere(where) }]
|
|
103
|
+
: parameters;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type DatasourceOptions, type ICommand, type IConnection, type IsolationLevelName, type ITransaction } from "@deterministic-code/datasources";
|
|
2
|
+
import type { JsonConnectionOptions } from "./connection-options.js";
|
|
3
|
+
import { type IFileStore } from "./file-store.js";
|
|
4
|
+
export declare class JsonConnection implements IConnection {
|
|
5
|
+
readonly provider = "json";
|
|
6
|
+
path: string;
|
|
7
|
+
collection?: string;
|
|
8
|
+
fileStore: IFileStore;
|
|
9
|
+
data: unknown;
|
|
10
|
+
isOpen: boolean;
|
|
11
|
+
inTransaction: boolean;
|
|
12
|
+
private snapshot;
|
|
13
|
+
private readonly initialData?;
|
|
14
|
+
private readonly hasInitialData;
|
|
15
|
+
static from: (options?: DatasourceOptions) => JsonConnection;
|
|
16
|
+
constructor(options?: JsonConnectionOptions);
|
|
17
|
+
createCommand: () => ICommand;
|
|
18
|
+
open(): Promise<void>;
|
|
19
|
+
close(): Promise<void>;
|
|
20
|
+
[Symbol.asyncDispose]: () => Promise<void>;
|
|
21
|
+
startTransaction(isolation?: IsolationLevelName): Promise<ITransaction>;
|
|
22
|
+
getCollection(): unknown[];
|
|
23
|
+
persist(): Promise<void>;
|
|
24
|
+
finishCommit(): void;
|
|
25
|
+
finishAbort(): void;
|
|
26
|
+
ensureOpen(): void;
|
|
27
|
+
private emptyData;
|
|
28
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { DatasourceError, DatasourceUrlParser, IsolationLevel, } from "@deterministic-code/datasources";
|
|
2
|
+
import { JsonCommand } from "./command.js";
|
|
3
|
+
import { MemoryFileStore } from "./file-store.js";
|
|
4
|
+
import { JsonTransaction } from "./transaction.js";
|
|
5
|
+
export class JsonConnection {
|
|
6
|
+
provider = "json";
|
|
7
|
+
path;
|
|
8
|
+
collection;
|
|
9
|
+
fileStore;
|
|
10
|
+
data;
|
|
11
|
+
isOpen = false;
|
|
12
|
+
inTransaction = false;
|
|
13
|
+
snapshot;
|
|
14
|
+
initialData;
|
|
15
|
+
hasInitialData;
|
|
16
|
+
static from = (options) => new JsonConnection({
|
|
17
|
+
path: DatasourceUrlParser.parse(options?.DATASOURCE_URL)?.datasource ?? "",
|
|
18
|
+
});
|
|
19
|
+
constructor(options = {}) {
|
|
20
|
+
this.path = options.path ?? "";
|
|
21
|
+
this.collection = options.collection;
|
|
22
|
+
this.fileStore = options.fileStore ?? new MemoryFileStore();
|
|
23
|
+
this.hasInitialData = Object.prototype.hasOwnProperty.call(options, "data");
|
|
24
|
+
this.initialData = options.data;
|
|
25
|
+
this.data = this.emptyData();
|
|
26
|
+
}
|
|
27
|
+
createCommand = () => new JsonCommand(this);
|
|
28
|
+
async open() {
|
|
29
|
+
if (this.isOpen)
|
|
30
|
+
throw new DatasourceError("Connection is already open");
|
|
31
|
+
if (this.hasInitialData) {
|
|
32
|
+
this.data = structuredClone(this.initialData);
|
|
33
|
+
}
|
|
34
|
+
else if (this.path && (await this.fileStore.exists(this.path))) {
|
|
35
|
+
const contents = await this.fileStore.read(this.path);
|
|
36
|
+
this.data = JSON.parse(contents);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
this.data = this.emptyData();
|
|
40
|
+
}
|
|
41
|
+
if (this.collection) {
|
|
42
|
+
this.getCollection();
|
|
43
|
+
}
|
|
44
|
+
this.isOpen = true;
|
|
45
|
+
}
|
|
46
|
+
async close() {
|
|
47
|
+
this.isOpen = false;
|
|
48
|
+
}
|
|
49
|
+
[Symbol.asyncDispose] = () => this.close();
|
|
50
|
+
async startTransaction(isolation = IsolationLevel.Serializable) {
|
|
51
|
+
this.ensureOpen();
|
|
52
|
+
this.snapshot = structuredClone(this.data);
|
|
53
|
+
this.inTransaction = true;
|
|
54
|
+
return new JsonTransaction(this, isolation);
|
|
55
|
+
}
|
|
56
|
+
getCollection() {
|
|
57
|
+
if (this.collection) {
|
|
58
|
+
if (this.data === null || typeof this.data !== "object" || Array.isArray(this.data)) {
|
|
59
|
+
this.data = {};
|
|
60
|
+
}
|
|
61
|
+
const root = this.data;
|
|
62
|
+
if (!Array.isArray(root[this.collection])) {
|
|
63
|
+
root[this.collection] = [];
|
|
64
|
+
}
|
|
65
|
+
return root[this.collection];
|
|
66
|
+
}
|
|
67
|
+
if (!Array.isArray(this.data)) {
|
|
68
|
+
this.data = [];
|
|
69
|
+
}
|
|
70
|
+
return this.data;
|
|
71
|
+
}
|
|
72
|
+
async persist() {
|
|
73
|
+
if (this.inTransaction || !this.path) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
await this.fileStore.write(this.path, JSON.stringify(this.data));
|
|
77
|
+
}
|
|
78
|
+
finishCommit() {
|
|
79
|
+
this.inTransaction = false;
|
|
80
|
+
this.snapshot = undefined;
|
|
81
|
+
}
|
|
82
|
+
finishAbort() {
|
|
83
|
+
this.data = this.snapshot;
|
|
84
|
+
this.inTransaction = false;
|
|
85
|
+
this.snapshot = undefined;
|
|
86
|
+
}
|
|
87
|
+
ensureOpen() {
|
|
88
|
+
if (!this.isOpen)
|
|
89
|
+
throw new DatasourceError("Connection is not open");
|
|
90
|
+
}
|
|
91
|
+
emptyData = () => (this.collection ? {} : []);
|
|
92
|
+
}
|
package/dist/filter.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare function parseFilter(text?: string | null): Record<string, unknown>;
|
|
2
|
+
export declare function matches(obj: Record<string, unknown>, filter: Record<string, unknown>): boolean;
|
|
3
|
+
export declare function asRecord(obj: unknown): Record<string, unknown>;
|
|
4
|
+
export declare function parametersToObject(parameters?: {
|
|
5
|
+
name: string;
|
|
6
|
+
value: unknown;
|
|
7
|
+
}[]): Record<string, unknown>;
|
package/dist/filter.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export function parseFilter(text) {
|
|
2
|
+
if (text === undefined || text === null || text.trim() === "") {
|
|
3
|
+
return {};
|
|
4
|
+
}
|
|
5
|
+
const parsed = JSON.parse(text);
|
|
6
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
7
|
+
throw new Error("JSON filter must be an object");
|
|
8
|
+
}
|
|
9
|
+
return parsed;
|
|
10
|
+
}
|
|
11
|
+
export function matches(obj, filter) {
|
|
12
|
+
return Object.entries(filter).every(([key, value]) => obj[key] === value);
|
|
13
|
+
}
|
|
14
|
+
export function asRecord(obj) {
|
|
15
|
+
if (obj === null || typeof obj !== "object" || Array.isArray(obj)) {
|
|
16
|
+
throw new Error("Repository objects must be plain objects");
|
|
17
|
+
}
|
|
18
|
+
return obj;
|
|
19
|
+
}
|
|
20
|
+
export function parametersToObject(parameters) {
|
|
21
|
+
const record = {};
|
|
22
|
+
if (!parameters) {
|
|
23
|
+
return record;
|
|
24
|
+
}
|
|
25
|
+
for (const parameter of parameters) {
|
|
26
|
+
record[parameter.name] = parameter.value;
|
|
27
|
+
}
|
|
28
|
+
return record;
|
|
29
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface IFileStore {
|
|
2
|
+
read(path: string): Promise<string>;
|
|
3
|
+
write(path: string, contents: string): Promise<void>;
|
|
4
|
+
exists(path: string): Promise<boolean>;
|
|
5
|
+
}
|
|
6
|
+
export interface FileSystemApi {
|
|
7
|
+
readFile(path: string, encoding: "utf8"): Promise<string>;
|
|
8
|
+
writeFile(path: string, contents: string, encoding: "utf8"): Promise<void>;
|
|
9
|
+
access(path: string): Promise<void>;
|
|
10
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { JsonDriver } from "./JsonDriver.js";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { JsonDriver } from "./JsonDriver.js";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { IFileStore } from "./i-file-store.js";
|
|
2
|
+
export declare class MemoryFileStore implements IFileStore {
|
|
3
|
+
files: Map<string, string>;
|
|
4
|
+
constructor(files?: Map<string, string>);
|
|
5
|
+
read(path: string): Promise<string>;
|
|
6
|
+
write(path: string, contents: string): Promise<void>;
|
|
7
|
+
exists(path: string): Promise<boolean>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export class MemoryFileStore {
|
|
2
|
+
files;
|
|
3
|
+
constructor(files = new Map()) {
|
|
4
|
+
this.files = files;
|
|
5
|
+
}
|
|
6
|
+
async read(path) {
|
|
7
|
+
const contents = this.files.get(path);
|
|
8
|
+
if (contents === undefined)
|
|
9
|
+
throw new Error(`File not found: ${path}`);
|
|
10
|
+
return contents;
|
|
11
|
+
}
|
|
12
|
+
async write(path, contents) {
|
|
13
|
+
this.files.set(path, contents);
|
|
14
|
+
}
|
|
15
|
+
async exists(path) {
|
|
16
|
+
return this.files.has(path);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { FileSystemApi, IFileStore } from "./i-file-store.js";
|
|
2
|
+
export declare class NodeFileStore implements IFileStore {
|
|
3
|
+
private readonly fs;
|
|
4
|
+
constructor(fs?: FileSystemApi);
|
|
5
|
+
read(path: string): Promise<string>;
|
|
6
|
+
write(path: string, contents: string): Promise<void>;
|
|
7
|
+
exists(path: string): Promise<boolean>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import * as nodeFs from "node:fs/promises";
|
|
2
|
+
const defaultFs = {
|
|
3
|
+
readFile: (path, encoding) => nodeFs.readFile(path, encoding),
|
|
4
|
+
writeFile: (path, contents, encoding) => nodeFs.writeFile(path, contents, encoding),
|
|
5
|
+
access: (path) => nodeFs.access(path),
|
|
6
|
+
};
|
|
7
|
+
export class NodeFileStore {
|
|
8
|
+
fs;
|
|
9
|
+
constructor(fs = defaultFs) {
|
|
10
|
+
this.fs = fs;
|
|
11
|
+
}
|
|
12
|
+
async read(path) {
|
|
13
|
+
return this.fs.readFile(path, "utf8");
|
|
14
|
+
}
|
|
15
|
+
async write(path, contents) {
|
|
16
|
+
await this.fs.writeFile(path, contents, "utf8");
|
|
17
|
+
}
|
|
18
|
+
async exists(path) {
|
|
19
|
+
try {
|
|
20
|
+
await this.fs.access(path);
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type ITransaction, type IsolationLevelName } from "@deterministic-code/datasources";
|
|
2
|
+
import type { JsonConnection } from "./connection.js";
|
|
3
|
+
export declare class JsonTransaction implements ITransaction {
|
|
4
|
+
readonly connection: JsonConnection;
|
|
5
|
+
readonly isolation: IsolationLevelName;
|
|
6
|
+
constructor(connection: JsonConnection, isolation?: IsolationLevelName);
|
|
7
|
+
commit(): Promise<void>;
|
|
8
|
+
abort(): Promise<void>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { IsolationLevel, } from "@deterministic-code/datasources";
|
|
2
|
+
export class JsonTransaction {
|
|
3
|
+
connection;
|
|
4
|
+
isolation;
|
|
5
|
+
constructor(connection, isolation = IsolationLevel.ReadCommitted) {
|
|
6
|
+
this.connection = connection;
|
|
7
|
+
this.isolation = isolation;
|
|
8
|
+
}
|
|
9
|
+
async commit() {
|
|
10
|
+
this.connection.finishCommit();
|
|
11
|
+
if (this.connection.path) {
|
|
12
|
+
await this.connection.fileStore.write(this.connection.path, JSON.stringify(this.connection.data));
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
async abort() {
|
|
16
|
+
this.connection.finishAbort();
|
|
17
|
+
}
|
|
18
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deterministic-code/datasources-json",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.3",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.js",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.js",
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"default": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"publishConfig": {
|
|
18
|
+
"access": "public"
|
|
19
|
+
},
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@deterministic-code/datasources": "^0.1.3"
|
|
22
|
+
}
|
|
23
|
+
}
|
package/README.md
DELETED