@malloydata/malloy 0.0.232-dev250118020814 → 0.0.232-dev250127221938
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/index.d.ts +3 -3
- package/dist/index.js +3 -1
- package/dist/malloy.d.ts +88 -19
- package/dist/malloy.js +265 -117
- package/dist/runtime_types.d.ts +6 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -4,10 +4,10 @@ export type { QueryDataRow, StructDef, TableSourceDef, SQLSourceDef, SourceDef,
|
|
|
4
4
|
export { isSourceDef, Segment, isLeafAtomic, isJoined, isJoinedSource, isSamplingEnable, isSamplingPercent, isSamplingRows, isRepeatedRecord, isScalarArray, mkArrayDef, mkFieldDef, expressionIsAggregate, expressionIsAnalytic, expressionIsCalculation, expressionIsScalar, expressionIsUngroupedAggregate, indent, composeSQLExpr, } from './model';
|
|
5
5
|
export { MalloyTranslator, } from './lang';
|
|
6
6
|
export type { LogMessage, TranslateResponse } from './lang';
|
|
7
|
-
export { Model, Malloy, Runtime, AtomicFieldType, ConnectionRuntime, SingleConnectionRuntime, EmptyURLReader, InMemoryURLReader, FixedConnectionMap, MalloyError, JoinRelationship, SourceRelationship, DateTimeframe, TimestampTimeframe, PreparedResult, Result, QueryMaterializer, CSVWriter, JSONWriter, Parse, DataWriter, Explore, } from './malloy';
|
|
8
|
-
export type { PreparedQuery, Field, AtomicField, ExploreField, QueryField, SortableField, DataArray, DataRecord, DataColumn, DataArrayOrRecord, Loggable, ModelMaterializer, DocumentTablePath, DocumentSymbol, ResultJSON, PreparedResultMaterializer, ExploreMaterializer, WriteStream, SerializedExplore, DateField, TimestampField, } from './malloy';
|
|
7
|
+
export { Model, Malloy, Runtime, AtomicFieldType, ConnectionRuntime, SingleConnectionRuntime, EmptyURLReader, InMemoryURLReader, FixedConnectionMap, MalloyError, JoinRelationship, SourceRelationship, DateTimeframe, TimestampTimeframe, PreparedResult, Result, QueryMaterializer, CSVWriter, JSONWriter, Parse, DataWriter, Explore, InMemoryModelCache, CacheManager, } from './malloy';
|
|
8
|
+
export type { PreparedQuery, Field, AtomicField, ExploreField, QueryField, SortableField, DataArray, DataRecord, DataColumn, DataArrayOrRecord, Loggable, ModelMaterializer, DocumentTablePath, DocumentSymbol, ResultJSON, PreparedResultMaterializer, ExploreMaterializer, WriteStream, SerializedExplore, ModelCache, CachedModel, DateField, TimestampField, } from './malloy';
|
|
9
9
|
export type { QueryOptionsReader, RunSQLOptions } from './run_sql_options';
|
|
10
|
-
export type { EventStream, ModelString, ModelURL, QueryString, QueryURL, URLReader, } from './runtime_types';
|
|
10
|
+
export type { EventStream, ModelString, ModelURL, QueryString, QueryURL, URLReader, InvalidationKey, } from './runtime_types';
|
|
11
11
|
export type { Connection, ConnectionConfig, ConnectionFactory, ConnectionParameter, ConnectionParameterValue, ConnectionConfigSchema, FetchSchemaOptions, InfoConnection, LookupConnection, PersistSQLResults, PooledConnection, TestableConnection, StreamingConnection, } from './connection/types';
|
|
12
12
|
export { toAsyncGenerator } from './connection_utils';
|
|
13
13
|
export { type TagParse, Tag, type TagDict } from './tags';
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.InMemoryURLReader = exports.EmptyURLReader = exports.SingleConnectionRuntime = exports.ConnectionRuntime = exports.AtomicFieldType = exports.Runtime = exports.Malloy = exports.Model = exports.MalloyTranslator = exports.composeSQLExpr = exports.indent = exports.expressionIsUngroupedAggregate = exports.expressionIsScalar = exports.expressionIsCalculation = exports.expressionIsAnalytic = exports.expressionIsAggregate = exports.mkFieldDef = exports.mkArrayDef = exports.isScalarArray = exports.isRepeatedRecord = exports.isSamplingRows = exports.isSamplingPercent = exports.isSamplingEnable = exports.isJoinedSource = exports.isJoined = exports.isLeafAtomic = exports.Segment = exports.isSourceDef = exports.TinyParser = exports.Dialect = exports.spread = exports.literal = exports.variadicParam = exports.param = exports.makeParam = exports.sql = exports.maxScalar = exports.minAggregate = exports.anyExprType = exports.minScalar = exports.overload = exports.qtz = exports.arg = exports.registerDialect = exports.MySQLDialect = exports.SnowflakeDialect = exports.PostgresDialect = exports.TrinoDialect = exports.StandardSQLDialect = exports.DuckDBDialect = void 0;
|
|
4
|
-
exports.Tag = exports.toAsyncGenerator = exports.Explore = exports.DataWriter = exports.Parse = exports.JSONWriter = exports.CSVWriter = exports.QueryMaterializer = exports.Result = exports.PreparedResult = exports.TimestampTimeframe = exports.DateTimeframe = exports.SourceRelationship = exports.JoinRelationship = exports.MalloyError = exports.FixedConnectionMap = void 0;
|
|
4
|
+
exports.Tag = exports.toAsyncGenerator = exports.CacheManager = exports.InMemoryModelCache = exports.Explore = exports.DataWriter = exports.Parse = exports.JSONWriter = exports.CSVWriter = exports.QueryMaterializer = exports.Result = exports.PreparedResult = exports.TimestampTimeframe = exports.DateTimeframe = exports.SourceRelationship = exports.JoinRelationship = exports.MalloyError = exports.FixedConnectionMap = void 0;
|
|
5
5
|
/*
|
|
6
6
|
* Copyright 2023 Google LLC
|
|
7
7
|
*
|
|
@@ -94,6 +94,8 @@ Object.defineProperty(exports, "JSONWriter", { enumerable: true, get: function (
|
|
|
94
94
|
Object.defineProperty(exports, "Parse", { enumerable: true, get: function () { return malloy_1.Parse; } });
|
|
95
95
|
Object.defineProperty(exports, "DataWriter", { enumerable: true, get: function () { return malloy_1.DataWriter; } });
|
|
96
96
|
Object.defineProperty(exports, "Explore", { enumerable: true, get: function () { return malloy_1.Explore; } });
|
|
97
|
+
Object.defineProperty(exports, "InMemoryModelCache", { enumerable: true, get: function () { return malloy_1.InMemoryModelCache; } });
|
|
98
|
+
Object.defineProperty(exports, "CacheManager", { enumerable: true, get: function () { return malloy_1.CacheManager; } });
|
|
97
99
|
var connection_utils_1 = require("./connection_utils");
|
|
98
100
|
Object.defineProperty(exports, "toAsyncGenerator", { enumerable: true, get: function () { return connection_utils_1.toAsyncGenerator; } });
|
|
99
101
|
var tags_1 = require("./tags");
|
package/dist/malloy.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { RunSQLOptions } from './run_sql_options';
|
|
|
3
3
|
import { DocumentCompletion as DocumentCompletionDefinition, DocumentSymbol as DocumentSymbolDefinition, LogMessage, MalloyTranslator } from './lang';
|
|
4
4
|
import { DocumentHelpContext } from './lang/parse-tree-walkers/document-help-context-walker';
|
|
5
5
|
import { CompiledQuery, DocumentLocation, DocumentReference, BooleanFieldDef, JSONFieldDef, NumberFieldDef, StringFieldDef, FilterCondition, Query as InternalQuery, ModelDef, DocumentPosition as ModelDocumentPosition, NamedQuery, QueryData, QueryDataRow, QueryResult, SearchIndexResult, SearchValueMapResult, StructDef, TurtleDef, NativeUnsupportedFieldDef, QueryRunStats, ImportLocation, Annotation, SQLSentence, SQLSourceDef, AtomicFieldDef, DateFieldDef, TimestampFieldDef, SourceDef, QueryToMaterialize } from './model';
|
|
6
|
-
import { EventStream, ModelString, ModelURL, QueryString, QueryURL, URLReader } from './runtime_types';
|
|
6
|
+
import { EventStream, InvalidationKey, ModelString, ModelURL, QueryString, QueryURL, URLReader } from './runtime_types';
|
|
7
7
|
import { Connection, FetchSchemaOptions, InfoConnection, LookupConnection } from './connection/types';
|
|
8
8
|
import { Tag, TagParse, TagParseSpec, Taggable } from './tags';
|
|
9
9
|
import { Dialect } from './dialect';
|
|
@@ -30,6 +30,19 @@ interface CompileQueryOptions {
|
|
|
30
30
|
eventStream?: EventStream;
|
|
31
31
|
defaultRowLimit?: number;
|
|
32
32
|
}
|
|
33
|
+
type Compilable = {
|
|
34
|
+
parse: Parse;
|
|
35
|
+
url?: undefined;
|
|
36
|
+
source?: undefined;
|
|
37
|
+
} | {
|
|
38
|
+
url: URL;
|
|
39
|
+
parse?: undefined;
|
|
40
|
+
source?: undefined;
|
|
41
|
+
} | {
|
|
42
|
+
source: string;
|
|
43
|
+
parse?: undefined;
|
|
44
|
+
url?: undefined;
|
|
45
|
+
};
|
|
33
46
|
export declare class Malloy {
|
|
34
47
|
static get version(): string;
|
|
35
48
|
private static _parse;
|
|
@@ -68,13 +81,13 @@ export declare class Malloy {
|
|
|
68
81
|
* @param model A compiled model to build upon (optional).
|
|
69
82
|
* @return A (promise of a) compiled `Model`.
|
|
70
83
|
*/
|
|
71
|
-
static compile({
|
|
84
|
+
static compile({ url, source, parse, urlReader, connections, model, refreshSchemaCache, noThrowOnError, eventStream, replaceMaterializedReferences, materializedTablePrefix, importBaseURL, cacheManager, }: {
|
|
72
85
|
urlReader: URLReader;
|
|
73
86
|
connections: LookupConnection<InfoConnection>;
|
|
74
|
-
parse: Parse;
|
|
75
87
|
model?: Model;
|
|
76
88
|
replaceMaterializedReferences?: boolean;
|
|
77
|
-
|
|
89
|
+
cacheManager?: CacheManager;
|
|
90
|
+
} & Compilable & CompileOptions & CompileQueryOptions & ParseOptions): Promise<Model>;
|
|
78
91
|
/**
|
|
79
92
|
* A dialect must provide a response for every table, or the translator loop
|
|
80
93
|
* will never exit. Because there was a time when this happened, we throw
|
|
@@ -273,7 +286,8 @@ export declare class PreparedQuery implements Taggable {
|
|
|
273
286
|
*/
|
|
274
287
|
export declare class Parse {
|
|
275
288
|
private translator;
|
|
276
|
-
|
|
289
|
+
private invalidationKey?;
|
|
290
|
+
constructor(translator: MalloyTranslator, invalidationKey?: InvalidationKey | undefined);
|
|
277
291
|
/**
|
|
278
292
|
* Retrieve the symbols defined in the parsed document.
|
|
279
293
|
*
|
|
@@ -292,6 +306,7 @@ export declare class Parse {
|
|
|
292
306
|
*/
|
|
293
307
|
get tablePathInfo(): DocumentTablePath[];
|
|
294
308
|
get _translator(): MalloyTranslator;
|
|
309
|
+
get _invalidationKey(): InvalidationKey | undefined;
|
|
295
310
|
completions(position: {
|
|
296
311
|
line: number;
|
|
297
312
|
character: number;
|
|
@@ -473,15 +488,24 @@ export declare class PreparedResult implements Taggable {
|
|
|
473
488
|
* Useful for scenarios in which `import` statements are not required.
|
|
474
489
|
*/
|
|
475
490
|
export declare class EmptyURLReader implements URLReader {
|
|
476
|
-
readURL(_url: URL): Promise<
|
|
491
|
+
readURL(_url: URL): Promise<{
|
|
492
|
+
contents: string;
|
|
493
|
+
invalidationKey: InvalidationKey;
|
|
494
|
+
}>;
|
|
495
|
+
getInvalidationKey(_url: URL): Promise<InvalidationKey>;
|
|
477
496
|
}
|
|
478
497
|
/**
|
|
479
498
|
* A URL reader backed by an in-memory mapping of URL contents.
|
|
480
499
|
*/
|
|
481
500
|
export declare class InMemoryURLReader implements URLReader {
|
|
482
|
-
|
|
501
|
+
protected files: Map<string, string>;
|
|
483
502
|
constructor(files: Map<string, string>);
|
|
484
|
-
readURL(url: URL): Promise<
|
|
503
|
+
readURL(url: URL): Promise<{
|
|
504
|
+
contents: string;
|
|
505
|
+
invalidationKey: InvalidationKey;
|
|
506
|
+
}>;
|
|
507
|
+
getInvalidationKey(url: URL): Promise<InvalidationKey>;
|
|
508
|
+
private invalidationKey;
|
|
485
509
|
}
|
|
486
510
|
/**
|
|
487
511
|
* A fixed mapping of connection names to connections.
|
|
@@ -726,6 +750,13 @@ export declare class ExploreField extends Explore {
|
|
|
726
750
|
get parentExplore(): Explore;
|
|
727
751
|
get sourceClasses(): string[];
|
|
728
752
|
}
|
|
753
|
+
type Connectionable = {
|
|
754
|
+
connection: Connection;
|
|
755
|
+
connections?: undefined;
|
|
756
|
+
} | {
|
|
757
|
+
connections: LookupConnection<Connection>;
|
|
758
|
+
connection?: undefined;
|
|
759
|
+
};
|
|
729
760
|
/**
|
|
730
761
|
* An environment for compiling and running Malloy queries.
|
|
731
762
|
*/
|
|
@@ -734,11 +765,16 @@ export declare class Runtime {
|
|
|
734
765
|
private _urlReader;
|
|
735
766
|
private _connections;
|
|
736
767
|
private _eventStream;
|
|
737
|
-
|
|
738
|
-
constructor(
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
768
|
+
private _cacheManager;
|
|
769
|
+
constructor({ urlReader, connections, connection, eventStream, cacheManager, }: {
|
|
770
|
+
urlReader?: URLReader;
|
|
771
|
+
eventStream?: EventStream;
|
|
772
|
+
cacheManager?: CacheManager;
|
|
773
|
+
} & Connectionable);
|
|
774
|
+
/**
|
|
775
|
+
* @return The `CacheManager` for this runtime instance.
|
|
776
|
+
*/
|
|
777
|
+
get cacheManager(): CacheManager | undefined;
|
|
742
778
|
/**
|
|
743
779
|
* @return The `URLReader` for this runtime instance.
|
|
744
780
|
*/
|
|
@@ -823,15 +859,19 @@ export declare class Runtime {
|
|
|
823
859
|
}
|
|
824
860
|
export declare class ConnectionRuntime extends Runtime {
|
|
825
861
|
readonly rawConnections: Connection[];
|
|
826
|
-
constructor(
|
|
827
|
-
|
|
862
|
+
constructor({ urlReader, connections, }: {
|
|
863
|
+
urlReader?: URLReader;
|
|
864
|
+
connections: Connection[];
|
|
865
|
+
});
|
|
828
866
|
}
|
|
829
867
|
export declare class SingleConnectionRuntime<T extends Connection = Connection> extends Runtime {
|
|
830
868
|
readonly connection: T;
|
|
831
|
-
constructor(urlReader
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
869
|
+
constructor({ urlReader, connection, eventStream, cacheManager, }: {
|
|
870
|
+
urlReader?: URLReader;
|
|
871
|
+
eventStream?: EventStream;
|
|
872
|
+
cacheManager?: CacheManager;
|
|
873
|
+
connection: T;
|
|
874
|
+
});
|
|
835
875
|
get supportsNesting(): boolean;
|
|
836
876
|
quote(column: string): string;
|
|
837
877
|
get dialect(): Dialect;
|
|
@@ -1257,4 +1297,33 @@ export declare class CSVWriter extends DataWriter {
|
|
|
1257
1297
|
private getRowMatrix;
|
|
1258
1298
|
process(data: AsyncIterableIterator<DataRecord>): Promise<void>;
|
|
1259
1299
|
}
|
|
1300
|
+
interface CacheGetModelDefResponse {
|
|
1301
|
+
modelDef: ModelDef;
|
|
1302
|
+
invalidationKeys: {
|
|
1303
|
+
[url: string]: InvalidationKey;
|
|
1304
|
+
};
|
|
1305
|
+
}
|
|
1306
|
+
export interface ModelCache {
|
|
1307
|
+
getModel(url: URL): Promise<CachedModel | undefined>;
|
|
1308
|
+
setModel(url: URL, cachedModel: CachedModel): Promise<boolean>;
|
|
1309
|
+
}
|
|
1310
|
+
export declare class CacheManager {
|
|
1311
|
+
private modelCache;
|
|
1312
|
+
private modelDependencies;
|
|
1313
|
+
private modelInvalidationKeys;
|
|
1314
|
+
constructor(modelCache: ModelCache);
|
|
1315
|
+
getCachedModelDef(urlReader: URLReader, url: string): Promise<CacheGetModelDefResponse | undefined>;
|
|
1316
|
+
setCachedModelDef(url: string, cachedModel: CachedModel): Promise<boolean>;
|
|
1317
|
+
}
|
|
1318
|
+
export interface CachedModel {
|
|
1319
|
+
modelDef: ModelDef;
|
|
1320
|
+
invalidationKeys: {
|
|
1321
|
+
[url: string]: InvalidationKey;
|
|
1322
|
+
};
|
|
1323
|
+
}
|
|
1324
|
+
export declare class InMemoryModelCache implements ModelCache {
|
|
1325
|
+
private readonly models;
|
|
1326
|
+
getModel(url: URL): Promise<CachedModel | undefined>;
|
|
1327
|
+
setModel(url: URL, cachedModel: CachedModel): Promise<boolean>;
|
|
1328
|
+
}
|
|
1260
1329
|
export {};
|
package/dist/malloy.js
CHANGED
|
@@ -22,20 +22,22 @@
|
|
|
22
22
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
23
23
|
*/
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
-
exports.CSVWriter = exports.JSONWriter = exports.DataWriter = exports.DataRecord = exports.DataArray = exports.Result = exports.ExploreMaterializer = exports.PreparedResultMaterializer = exports.QueryMaterializer = exports.ModelMaterializer = exports.SingleConnectionRuntime = exports.ConnectionRuntime = exports.Runtime = exports.ExploreField = exports.JoinRelationship = exports.QueryField = exports.Query = exports.StringField = exports.UnsupportedField = exports.JSONField = exports.BooleanField = exports.NumberField = exports.TimestampField = exports.DateField = exports.TimestampTimeframe = exports.DateTimeframe = exports.AtomicField = exports.AtomicFieldType = exports.Explore = exports.SourceRelationship = exports.FixedConnectionMap = exports.InMemoryURLReader = exports.EmptyURLReader = exports.PreparedResult = exports.DocumentCompletion = exports.DocumentSymbol = exports.DocumentPosition = exports.DocumentRange = exports.DocumentTablePath = exports.Parse = exports.PreparedQuery = exports.Model = exports.MalloyError = exports.Malloy = void 0;
|
|
25
|
+
exports.InMemoryModelCache = exports.CacheManager = exports.CSVWriter = exports.JSONWriter = exports.DataWriter = exports.DataRecord = exports.DataArray = exports.Result = exports.ExploreMaterializer = exports.PreparedResultMaterializer = exports.QueryMaterializer = exports.ModelMaterializer = exports.SingleConnectionRuntime = exports.ConnectionRuntime = exports.Runtime = exports.ExploreField = exports.JoinRelationship = exports.QueryField = exports.Query = exports.StringField = exports.UnsupportedField = exports.JSONField = exports.BooleanField = exports.NumberField = exports.TimestampField = exports.DateField = exports.TimestampTimeframe = exports.DateTimeframe = exports.AtomicField = exports.AtomicFieldType = exports.Explore = exports.SourceRelationship = exports.FixedConnectionMap = exports.InMemoryURLReader = exports.EmptyURLReader = exports.PreparedResult = exports.DocumentCompletion = exports.DocumentSymbol = exports.DocumentPosition = exports.DocumentRange = exports.DocumentTablePath = exports.Parse = exports.PreparedQuery = exports.Model = exports.MalloyError = exports.Malloy = void 0;
|
|
26
26
|
const lang_1 = require("./lang");
|
|
27
27
|
const model_1 = require("./model");
|
|
28
28
|
const luxon_1 = require("luxon");
|
|
29
29
|
const tags_1 = require("./tags");
|
|
30
30
|
const dialect_1 = require("./dialect");
|
|
31
31
|
const version_1 = require("./version");
|
|
32
|
+
const uuid_1 = require("uuid");
|
|
33
|
+
const MALLOY_INTERNAL_URL = 'internal://internal.malloy';
|
|
32
34
|
class Malloy {
|
|
33
35
|
static get version() {
|
|
34
36
|
return version_1.MALLOY_VERSION;
|
|
35
37
|
}
|
|
36
|
-
static _parse(source, url, eventStream, options) {
|
|
38
|
+
static _parse(source, url, eventStream, options, invalidationKey) {
|
|
37
39
|
if (url === undefined) {
|
|
38
|
-
url = new URL(
|
|
40
|
+
url = new URL(MALLOY_INTERNAL_URL);
|
|
39
41
|
}
|
|
40
42
|
let importBaseURL = url;
|
|
41
43
|
if (options === null || options === void 0 ? void 0 : options.importBaseURL) {
|
|
@@ -47,7 +49,7 @@ class Malloy {
|
|
|
47
49
|
if (options === null || options === void 0 ? void 0 : options.testEnvironment) {
|
|
48
50
|
translator.allDialectsEnabled = true;
|
|
49
51
|
}
|
|
50
|
-
return new Parse(translator);
|
|
52
|
+
return new Parse(translator, invalidationKey);
|
|
51
53
|
}
|
|
52
54
|
static parse({ url, urlReader, source, eventStream, options, }) {
|
|
53
55
|
if (source !== undefined) {
|
|
@@ -60,8 +62,8 @@ class Malloy {
|
|
|
60
62
|
if (url === undefined) {
|
|
61
63
|
throw new Error('Internal Error: url is required if source not present.');
|
|
62
64
|
}
|
|
63
|
-
return
|
|
64
|
-
return Malloy._parse(
|
|
65
|
+
return readURL(urlReader, url).then(({ contents, invalidationKey }) => {
|
|
66
|
+
return Malloy._parse(contents, url, eventStream, options, invalidationKey);
|
|
65
67
|
});
|
|
66
68
|
}
|
|
67
69
|
}
|
|
@@ -74,8 +76,8 @@ class Malloy {
|
|
|
74
76
|
* @param model A compiled model to build upon (optional).
|
|
75
77
|
* @return A (promise of a) compiled `Model`.
|
|
76
78
|
*/
|
|
77
|
-
static async compile({
|
|
78
|
-
var _a, _b, _c, _d;
|
|
79
|
+
static async compile({ url, source, parse, urlReader, connections, model, refreshSchemaCache, noThrowOnError, eventStream, replaceMaterializedReferences, materializedTablePrefix, importBaseURL, cacheManager, }) {
|
|
80
|
+
var _a, _b, _c, _d, _e;
|
|
79
81
|
let refreshTimestamp;
|
|
80
82
|
if (refreshSchemaCache) {
|
|
81
83
|
refreshTimestamp =
|
|
@@ -83,12 +85,67 @@ class Malloy {
|
|
|
83
85
|
? refreshSchemaCache
|
|
84
86
|
: Date.now();
|
|
85
87
|
}
|
|
86
|
-
|
|
88
|
+
if (url === undefined && source === undefined && parse === undefined) {
|
|
89
|
+
throw new Error('Internal Error: url, source, or parse required.');
|
|
90
|
+
}
|
|
91
|
+
if (url === undefined) {
|
|
92
|
+
if (parse !== undefined) {
|
|
93
|
+
url = new URL(parse._translator.sourceURL);
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
url = new URL(MALLOY_INTERNAL_URL);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
const invalidationKeys = {};
|
|
100
|
+
// Before anything, if we have a URL and not source code, we check if that URL
|
|
101
|
+
// is cached.
|
|
102
|
+
if (source === undefined && cacheManager !== undefined) {
|
|
103
|
+
const cached = await cacheManager.getCachedModelDef(urlReader, url.toString());
|
|
104
|
+
if (cached) {
|
|
105
|
+
return new Model(cached.modelDef, [], // TODO when using a model from cache, should we also store the problems??
|
|
106
|
+
[url.toString(), ...flatDeps(cached.modelDef.dependencies)]
|
|
107
|
+
// TODO maybe implement referenceAt and importAt by re-translating the model?
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
importBaseURL !== null && importBaseURL !== void 0 ? importBaseURL : (importBaseURL = url);
|
|
112
|
+
let translator;
|
|
113
|
+
// It's not cached, so we may need to get the actual source
|
|
114
|
+
const _url = url.toString();
|
|
115
|
+
if (parse !== undefined) {
|
|
116
|
+
translator = parse._translator;
|
|
117
|
+
const invalidationKey = (_a = parse._invalidationKey) !== null && _a !== void 0 ? _a : (await getInvalidationKey(urlReader, url));
|
|
118
|
+
invalidationKeys[_url] = invalidationKey;
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
if (source === undefined) {
|
|
122
|
+
const { contents, invalidationKey } = await readURL(urlReader, url);
|
|
123
|
+
invalidationKeys[_url] = invalidationKey;
|
|
124
|
+
source = contents;
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
const invalidationKey = await getInvalidationKey(urlReader, url);
|
|
128
|
+
invalidationKeys[_url] = invalidationKey;
|
|
129
|
+
}
|
|
130
|
+
translator = new lang_1.MalloyTranslator(_url, importBaseURL.toString(), {
|
|
131
|
+
urls: { [_url]: source },
|
|
132
|
+
}, eventStream);
|
|
133
|
+
}
|
|
87
134
|
for (;;) {
|
|
88
135
|
const result = translator.translate(model === null || model === void 0 ? void 0 : model._modelDef);
|
|
89
136
|
if (result.final) {
|
|
90
137
|
if (result.modelDef) {
|
|
91
|
-
|
|
138
|
+
await (cacheManager === null || cacheManager === void 0 ? void 0 : cacheManager.setCachedModelDef(url.toString(), {
|
|
139
|
+
modelDef: result.modelDef,
|
|
140
|
+
invalidationKeys,
|
|
141
|
+
}));
|
|
142
|
+
for (const model of translator.newlyTranslatedDependencies()) {
|
|
143
|
+
await (cacheManager === null || cacheManager === void 0 ? void 0 : cacheManager.setCachedModelDef(model.url, {
|
|
144
|
+
modelDef: model.modelDef,
|
|
145
|
+
invalidationKeys,
|
|
146
|
+
}));
|
|
147
|
+
}
|
|
148
|
+
return new Model(result.modelDef, result.problems || [], [...((_b = model === null || model === void 0 ? void 0 : model.fromSources) !== null && _b !== void 0 ? _b : []), ...((_c = result.fromSources) !== null && _c !== void 0 ? _c : [])], (position) => translator.referenceAt(position), (position) => translator.importAt(position));
|
|
92
149
|
}
|
|
93
150
|
else if (noThrowOnError) {
|
|
94
151
|
const emptyModel = {
|
|
@@ -99,7 +156,7 @@ class Malloy {
|
|
|
99
156
|
queryList: [],
|
|
100
157
|
};
|
|
101
158
|
const modelFromCompile = (model === null || model === void 0 ? void 0 : model._modelDef) || emptyModel;
|
|
102
|
-
return new Model(modelFromCompile, result.problems || [], [...((
|
|
159
|
+
return new Model(modelFromCompile, result.problems || [], [...((_d = model === null || model === void 0 ? void 0 : model.fromSources) !== null && _d !== void 0 ? _d : []), ...((_e = result.fromSources) !== null && _e !== void 0 ? _e : [])], (position) => translator.referenceAt(position), (position) => translator.importAt(position));
|
|
103
160
|
}
|
|
104
161
|
else {
|
|
105
162
|
const errors = result.problems || [];
|
|
@@ -113,11 +170,27 @@ class Malloy {
|
|
|
113
170
|
if (result.urls) {
|
|
114
171
|
for (const neededUrl of result.urls) {
|
|
115
172
|
try {
|
|
116
|
-
if (neededUrl
|
|
173
|
+
if (isInternalURL(neededUrl)) {
|
|
117
174
|
throw new Error('In order to use relative imports, you must compile a file via a URL.');
|
|
118
175
|
}
|
|
119
|
-
|
|
120
|
-
|
|
176
|
+
// First, check the cache
|
|
177
|
+
if (cacheManager !== undefined) {
|
|
178
|
+
const cached = await cacheManager.getCachedModelDef(urlReader, neededUrl);
|
|
179
|
+
if (cached) {
|
|
180
|
+
for (const dependency in cached.invalidationKeys) {
|
|
181
|
+
invalidationKeys[dependency] =
|
|
182
|
+
cached.invalidationKeys[dependency];
|
|
183
|
+
}
|
|
184
|
+
translator.update({
|
|
185
|
+
translations: { [neededUrl]: cached.modelDef },
|
|
186
|
+
});
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
// Otherwise, fetch the URL contents
|
|
191
|
+
const { contents, invalidationKey } = await readURL(urlReader, new URL(neededUrl));
|
|
192
|
+
const urls = { [neededUrl]: contents };
|
|
193
|
+
invalidationKeys[neededUrl] = invalidationKey;
|
|
121
194
|
translator.update({ urls });
|
|
122
195
|
}
|
|
123
196
|
catch (error) {
|
|
@@ -548,8 +621,9 @@ exports.PreparedQuery = PreparedQuery;
|
|
|
548
621
|
* A parsed Malloy document.
|
|
549
622
|
*/
|
|
550
623
|
class Parse {
|
|
551
|
-
constructor(translator) {
|
|
624
|
+
constructor(translator, invalidationKey) {
|
|
552
625
|
this.translator = translator;
|
|
626
|
+
this.invalidationKey = invalidationKey;
|
|
553
627
|
}
|
|
554
628
|
/**
|
|
555
629
|
* Retrieve the symbols defined in the parsed document.
|
|
@@ -577,6 +651,9 @@ class Parse {
|
|
|
577
651
|
get _translator() {
|
|
578
652
|
return this.translator;
|
|
579
653
|
}
|
|
654
|
+
get _invalidationKey() {
|
|
655
|
+
return this.invalidationKey;
|
|
656
|
+
}
|
|
580
657
|
completions(position) {
|
|
581
658
|
return (this.translator.completions(position).completions || []).map(completion => new DocumentCompletion(completion));
|
|
582
659
|
}
|
|
@@ -846,6 +923,9 @@ class EmptyURLReader {
|
|
|
846
923
|
async readURL(_url) {
|
|
847
924
|
throw new Error('No files.');
|
|
848
925
|
}
|
|
926
|
+
async getInvalidationKey(_url) {
|
|
927
|
+
throw new Error('No files.');
|
|
928
|
+
}
|
|
849
929
|
}
|
|
850
930
|
exports.EmptyURLReader = EmptyURLReader;
|
|
851
931
|
/**
|
|
@@ -858,12 +938,30 @@ class InMemoryURLReader {
|
|
|
858
938
|
async readURL(url) {
|
|
859
939
|
const file = this.files.get(url.toString());
|
|
860
940
|
if (file !== undefined) {
|
|
861
|
-
return Promise.resolve(
|
|
941
|
+
return Promise.resolve({
|
|
942
|
+
contents: file,
|
|
943
|
+
invalidationKey: this.invalidationKey(url, file),
|
|
944
|
+
});
|
|
945
|
+
}
|
|
946
|
+
else {
|
|
947
|
+
throw new Error(`File not found '${url}'`);
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
async getInvalidationKey(url) {
|
|
951
|
+
const file = this.files.get(url.toString());
|
|
952
|
+
if (file !== undefined) {
|
|
953
|
+
return Promise.resolve(this.invalidationKey(url, file));
|
|
862
954
|
}
|
|
863
955
|
else {
|
|
864
956
|
throw new Error(`File not found '${url}'`);
|
|
865
957
|
}
|
|
866
958
|
}
|
|
959
|
+
invalidationKey(url, contents) {
|
|
960
|
+
if (isInternalURL(url.toString())) {
|
|
961
|
+
return null;
|
|
962
|
+
}
|
|
963
|
+
return hashForInvalidationKey(contents);
|
|
964
|
+
}
|
|
867
965
|
}
|
|
868
966
|
exports.InMemoryURLReader = InMemoryURLReader;
|
|
869
967
|
/**
|
|
@@ -1560,39 +1658,29 @@ exports.ExploreField = ExploreField;
|
|
|
1560
1658
|
* An environment for compiling and running Malloy queries.
|
|
1561
1659
|
*/
|
|
1562
1660
|
class Runtime {
|
|
1563
|
-
constructor(
|
|
1661
|
+
constructor({ urlReader, connections, connection, eventStream, cacheManager, }) {
|
|
1564
1662
|
this.isTestRuntime = false;
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
for (const arg of args) {
|
|
1569
|
-
if (arg === undefined) {
|
|
1570
|
-
continue;
|
|
1571
|
-
}
|
|
1572
|
-
else if (isURLReader(arg)) {
|
|
1573
|
-
urlReader = arg;
|
|
1574
|
-
}
|
|
1575
|
-
else if (isLookupConnection(arg)) {
|
|
1576
|
-
connections = arg;
|
|
1577
|
-
}
|
|
1578
|
-
else if (isEventStream(arg)) {
|
|
1579
|
-
eventStream = arg;
|
|
1580
|
-
}
|
|
1581
|
-
else {
|
|
1582
|
-
connections = {
|
|
1583
|
-
lookupConnection: () => Promise.resolve(arg),
|
|
1584
|
-
};
|
|
1663
|
+
if (connections === undefined) {
|
|
1664
|
+
if (connection === undefined) {
|
|
1665
|
+
throw new Error('A LookupConnection<Connection> or Connection is required.');
|
|
1585
1666
|
}
|
|
1667
|
+
connections = {
|
|
1668
|
+
lookupConnection: () => Promise.resolve(connection),
|
|
1669
|
+
};
|
|
1586
1670
|
}
|
|
1587
1671
|
if (urlReader === undefined) {
|
|
1588
1672
|
urlReader = new EmptyURLReader();
|
|
1589
1673
|
}
|
|
1590
|
-
if (connections === undefined) {
|
|
1591
|
-
throw new Error('A LookupConnection<Connection> or Connection is required.');
|
|
1592
|
-
}
|
|
1593
1674
|
this._urlReader = urlReader;
|
|
1594
1675
|
this._connections = connections;
|
|
1595
1676
|
this._eventStream = eventStream;
|
|
1677
|
+
this._cacheManager = cacheManager;
|
|
1678
|
+
}
|
|
1679
|
+
/**
|
|
1680
|
+
* @return The `CacheManager` for this runtime instance.
|
|
1681
|
+
*/
|
|
1682
|
+
get cacheManager() {
|
|
1683
|
+
return this._cacheManager;
|
|
1596
1684
|
}
|
|
1597
1685
|
/**
|
|
1598
1686
|
* @return The `URLReader` for this runtime instance.
|
|
@@ -1629,28 +1717,20 @@ class Runtime {
|
|
|
1629
1717
|
options = { ...options, testEnvironment: true };
|
|
1630
1718
|
}
|
|
1631
1719
|
}
|
|
1720
|
+
const compilable = source instanceof URL ? { url: source } : { source };
|
|
1632
1721
|
return new ModelMaterializer(this, async () => {
|
|
1633
|
-
const parse = source instanceof URL
|
|
1634
|
-
? await Malloy.parse({
|
|
1635
|
-
url: source,
|
|
1636
|
-
urlReader: this.urlReader,
|
|
1637
|
-
eventStream: this.eventStream,
|
|
1638
|
-
options,
|
|
1639
|
-
})
|
|
1640
|
-
: Malloy.parse({
|
|
1641
|
-
source,
|
|
1642
|
-
eventStream: this.eventStream,
|
|
1643
|
-
options,
|
|
1644
|
-
});
|
|
1645
1722
|
return Malloy.compile({
|
|
1723
|
+
...compilable,
|
|
1646
1724
|
urlReader: this.urlReader,
|
|
1647
1725
|
connections: this.connections,
|
|
1648
|
-
parse,
|
|
1649
1726
|
refreshSchemaCache,
|
|
1650
1727
|
noThrowOnError,
|
|
1651
1728
|
eventStream: this.eventStream,
|
|
1652
1729
|
replaceMaterializedReferences: options === null || options === void 0 ? void 0 : options.replaceMaterializedReferences,
|
|
1653
1730
|
materializedTablePrefix: options === null || options === void 0 ? void 0 : options.materializedTablePrefix,
|
|
1731
|
+
importBaseURL: options === null || options === void 0 ? void 0 : options.importBaseURL,
|
|
1732
|
+
testEnvironment: options === null || options === void 0 ? void 0 : options.testEnvironment,
|
|
1733
|
+
cacheManager: this.cacheManager,
|
|
1654
1734
|
});
|
|
1655
1735
|
}, options);
|
|
1656
1736
|
}
|
|
@@ -1741,40 +1821,23 @@ class Runtime {
|
|
|
1741
1821
|
}
|
|
1742
1822
|
exports.Runtime = Runtime;
|
|
1743
1823
|
class ConnectionRuntime extends Runtime {
|
|
1744
|
-
constructor(
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
else {
|
|
1751
|
-
const connections = maybeConnections;
|
|
1752
|
-
super(urlsOrConnections, FixedConnectionMap.fromArray(connections));
|
|
1753
|
-
this.rawConnections = connections;
|
|
1754
|
-
}
|
|
1824
|
+
constructor({ urlReader, connections, }) {
|
|
1825
|
+
super({
|
|
1826
|
+
connections: FixedConnectionMap.fromArray(connections),
|
|
1827
|
+
urlReader,
|
|
1828
|
+
});
|
|
1829
|
+
this.rawConnections = connections;
|
|
1755
1830
|
}
|
|
1756
1831
|
}
|
|
1757
1832
|
exports.ConnectionRuntime = ConnectionRuntime;
|
|
1758
1833
|
class SingleConnectionRuntime extends Runtime {
|
|
1759
|
-
constructor(
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
}
|
|
1767
|
-
if (isConnection(param)) {
|
|
1768
|
-
connection = param;
|
|
1769
|
-
}
|
|
1770
|
-
if (isEventStream(param)) {
|
|
1771
|
-
eventStream = param;
|
|
1772
|
-
}
|
|
1773
|
-
}
|
|
1774
|
-
if (connection === undefined) {
|
|
1775
|
-
throw new Error('Expected connection to be passed into SingleConnectionRuntime');
|
|
1776
|
-
}
|
|
1777
|
-
super(urlReader, connection, eventStream);
|
|
1834
|
+
constructor({ urlReader, connection, eventStream, cacheManager, }) {
|
|
1835
|
+
super({
|
|
1836
|
+
urlReader,
|
|
1837
|
+
eventStream,
|
|
1838
|
+
cacheManager,
|
|
1839
|
+
connection,
|
|
1840
|
+
});
|
|
1778
1841
|
this.connection = connection;
|
|
1779
1842
|
}
|
|
1780
1843
|
get supportsNesting() {
|
|
@@ -1892,24 +1955,17 @@ class ModelMaterializer extends FluentState {
|
|
|
1892
1955
|
options = { ...options, testEnvironment: true };
|
|
1893
1956
|
}
|
|
1894
1957
|
}
|
|
1895
|
-
const
|
|
1896
|
-
? await Malloy.parse({
|
|
1897
|
-
url: query,
|
|
1898
|
-
urlReader,
|
|
1899
|
-
options,
|
|
1900
|
-
})
|
|
1901
|
-
: Malloy.parse({
|
|
1902
|
-
source: query,
|
|
1903
|
-
options,
|
|
1904
|
-
});
|
|
1958
|
+
const compilable = query instanceof URL ? { url: query } : { source: query };
|
|
1905
1959
|
const model = await this.getModel();
|
|
1906
1960
|
const queryModel = await Malloy.compile({
|
|
1961
|
+
...compilable,
|
|
1907
1962
|
urlReader,
|
|
1908
1963
|
connections,
|
|
1909
|
-
parse,
|
|
1910
1964
|
model,
|
|
1911
1965
|
refreshSchemaCache,
|
|
1912
1966
|
noThrowOnError,
|
|
1967
|
+
importBaseURL: options === null || options === void 0 ? void 0 : options.importBaseURL,
|
|
1968
|
+
testEnvironment: options === null || options === void 0 ? void 0 : options.testEnvironment,
|
|
1913
1969
|
...this.compileQueryOptions,
|
|
1914
1970
|
});
|
|
1915
1971
|
return queryModel.preparedQuery;
|
|
@@ -1934,24 +1990,17 @@ class ModelMaterializer extends FluentState {
|
|
|
1934
1990
|
return new ModelMaterializer(this.runtime, async () => {
|
|
1935
1991
|
const urlReader = this.runtime.urlReader;
|
|
1936
1992
|
const connections = this.runtime.connections;
|
|
1937
|
-
const
|
|
1938
|
-
? await Malloy.parse({
|
|
1939
|
-
url: query,
|
|
1940
|
-
urlReader,
|
|
1941
|
-
options,
|
|
1942
|
-
})
|
|
1943
|
-
: Malloy.parse({
|
|
1944
|
-
source: query,
|
|
1945
|
-
options,
|
|
1946
|
-
});
|
|
1993
|
+
const compilable = query instanceof URL ? { url: query } : { source: query };
|
|
1947
1994
|
const model = await this.getModel();
|
|
1948
1995
|
const queryModel = await Malloy.compile({
|
|
1996
|
+
...compilable,
|
|
1949
1997
|
urlReader,
|
|
1950
1998
|
connections,
|
|
1951
|
-
parse,
|
|
1952
1999
|
model,
|
|
1953
2000
|
refreshSchemaCache: options === null || options === void 0 ? void 0 : options.refreshSchemaCache,
|
|
1954
2001
|
noThrowOnError: options === null || options === void 0 ? void 0 : options.noThrowOnError,
|
|
2002
|
+
importBaseURL: options === null || options === void 0 ? void 0 : options.importBaseURL,
|
|
2003
|
+
testEnvironment: options === null || options === void 0 ? void 0 : options.testEnvironment,
|
|
1955
2004
|
...this.compileQueryOptions,
|
|
1956
2005
|
});
|
|
1957
2006
|
return queryModel;
|
|
@@ -2790,18 +2839,6 @@ class DataRecord extends Data {
|
|
|
2790
2839
|
}
|
|
2791
2840
|
}
|
|
2792
2841
|
exports.DataRecord = DataRecord;
|
|
2793
|
-
function isURLReader(thing) {
|
|
2794
|
-
return 'readURL' in thing;
|
|
2795
|
-
}
|
|
2796
|
-
function isLookupConnection(thing) {
|
|
2797
|
-
return 'lookupConnection' in thing;
|
|
2798
|
-
}
|
|
2799
|
-
function isEventStream(thing) {
|
|
2800
|
-
return 'emit' in thing;
|
|
2801
|
-
}
|
|
2802
|
-
function isConnection(thing) {
|
|
2803
|
-
return 'runSQL' in thing;
|
|
2804
|
-
}
|
|
2805
2842
|
class DataWriter {
|
|
2806
2843
|
constructor(stream) {
|
|
2807
2844
|
this.stream = stream;
|
|
@@ -3010,4 +3047,115 @@ class CSVWriter extends DataWriter {
|
|
|
3010
3047
|
}
|
|
3011
3048
|
}
|
|
3012
3049
|
exports.CSVWriter = CSVWriter;
|
|
3050
|
+
class CacheManager {
|
|
3051
|
+
constructor(modelCache) {
|
|
3052
|
+
this.modelCache = modelCache;
|
|
3053
|
+
this.modelDependencies = new Map();
|
|
3054
|
+
this.modelInvalidationKeys = new Map();
|
|
3055
|
+
}
|
|
3056
|
+
async getCachedModelDef(urlReader, url) {
|
|
3057
|
+
const _dependencies = this.modelDependencies.get(url);
|
|
3058
|
+
if (_dependencies === undefined) {
|
|
3059
|
+
return undefined;
|
|
3060
|
+
}
|
|
3061
|
+
const dependencies = [url, ...flatDeps(_dependencies)];
|
|
3062
|
+
const invalidationKeys = {};
|
|
3063
|
+
for (const dependency of dependencies) {
|
|
3064
|
+
const invalidationKey = this.modelInvalidationKeys.get(dependency);
|
|
3065
|
+
if (invalidationKey === undefined || invalidationKey === null) {
|
|
3066
|
+
return undefined;
|
|
3067
|
+
}
|
|
3068
|
+
invalidationKeys[dependency] = invalidationKey;
|
|
3069
|
+
}
|
|
3070
|
+
for (const dependency of dependencies) {
|
|
3071
|
+
const invalidationKey = await getInvalidationKey(urlReader, new URL(dependency));
|
|
3072
|
+
if (invalidationKey !== invalidationKeys[dependency]) {
|
|
3073
|
+
return undefined;
|
|
3074
|
+
}
|
|
3075
|
+
}
|
|
3076
|
+
const cached = await this.modelCache.getModel(new URL(url));
|
|
3077
|
+
if (cached === undefined) {
|
|
3078
|
+
return undefined;
|
|
3079
|
+
}
|
|
3080
|
+
for (const dependency of dependencies) {
|
|
3081
|
+
if (cached.invalidationKeys[dependency] !== invalidationKeys[dependency]) {
|
|
3082
|
+
return undefined;
|
|
3083
|
+
}
|
|
3084
|
+
}
|
|
3085
|
+
// Return the cached model def and the invalidation keys for this
|
|
3086
|
+
// model def's dependencies
|
|
3087
|
+
return { modelDef: cached.modelDef, invalidationKeys };
|
|
3088
|
+
}
|
|
3089
|
+
async setCachedModelDef(url, cachedModel) {
|
|
3090
|
+
this.modelDependencies.set(url, cachedModel.modelDef.dependencies);
|
|
3091
|
+
const invalidationKeys = {};
|
|
3092
|
+
for (const dependency of [
|
|
3093
|
+
url,
|
|
3094
|
+
...flatDeps(cachedModel.modelDef.dependencies),
|
|
3095
|
+
]) {
|
|
3096
|
+
if (cachedModel.invalidationKeys[dependency] === null) {
|
|
3097
|
+
return false;
|
|
3098
|
+
}
|
|
3099
|
+
if (cachedModel.invalidationKeys[dependency] === undefined) {
|
|
3100
|
+
throw new Error(`Missing invalidation key for dependency ${dependency}`);
|
|
3101
|
+
}
|
|
3102
|
+
this.modelInvalidationKeys.set(dependency, cachedModel.invalidationKeys[dependency]);
|
|
3103
|
+
invalidationKeys[dependency] = cachedModel.invalidationKeys[dependency];
|
|
3104
|
+
}
|
|
3105
|
+
const result = await this.modelCache.setModel(new URL(url), {
|
|
3106
|
+
modelDef: cachedModel.modelDef,
|
|
3107
|
+
invalidationKeys,
|
|
3108
|
+
});
|
|
3109
|
+
if (result) {
|
|
3110
|
+
return true; // TODO just return `result` when it's a boolean
|
|
3111
|
+
}
|
|
3112
|
+
return false;
|
|
3113
|
+
}
|
|
3114
|
+
}
|
|
3115
|
+
exports.CacheManager = CacheManager;
|
|
3116
|
+
function flatDeps(tree) {
|
|
3117
|
+
return [...Object.keys(tree), ...Object.values(tree).map(flatDeps).flat()];
|
|
3118
|
+
}
|
|
3119
|
+
// TODO maybe make this memory bounded....
|
|
3120
|
+
class InMemoryModelCache {
|
|
3121
|
+
constructor() {
|
|
3122
|
+
this.models = new Map();
|
|
3123
|
+
}
|
|
3124
|
+
async getModel(url) {
|
|
3125
|
+
return Promise.resolve(this.models.get(url.toString()));
|
|
3126
|
+
}
|
|
3127
|
+
async setModel(url, cachedModel) {
|
|
3128
|
+
this.models.set(url.toString(), cachedModel);
|
|
3129
|
+
return Promise.resolve(true);
|
|
3130
|
+
}
|
|
3131
|
+
}
|
|
3132
|
+
exports.InMemoryModelCache = InMemoryModelCache;
|
|
3133
|
+
function hashForInvalidationKey(input) {
|
|
3134
|
+
const MALLOY_UUID = '76c17e9d-f3ce-5f2d-bfde-98ad3d2a37f6';
|
|
3135
|
+
return (0, uuid_1.v5)(input, MALLOY_UUID);
|
|
3136
|
+
}
|
|
3137
|
+
async function readURL(urlReader, url) {
|
|
3138
|
+
const result = await urlReader.readURL(url);
|
|
3139
|
+
const { contents, invalidationKey } = typeof result === 'string'
|
|
3140
|
+
? { contents: result, invalidationKey: undefined }
|
|
3141
|
+
: result;
|
|
3142
|
+
return {
|
|
3143
|
+
contents,
|
|
3144
|
+
invalidationKey: isInternalURL(url.toString())
|
|
3145
|
+
? null
|
|
3146
|
+
: invalidationKey !== null && invalidationKey !== void 0 ? invalidationKey : hashForInvalidationKey(contents),
|
|
3147
|
+
};
|
|
3148
|
+
}
|
|
3149
|
+
async function getInvalidationKey(urlReader, url) {
|
|
3150
|
+
if (isInternalURL(url.toString())) {
|
|
3151
|
+
return null;
|
|
3152
|
+
}
|
|
3153
|
+
if (urlReader.getInvalidationKey !== undefined) {
|
|
3154
|
+
return await urlReader.getInvalidationKey(url);
|
|
3155
|
+
}
|
|
3156
|
+
return (await readURL(urlReader, url)).invalidationKey;
|
|
3157
|
+
}
|
|
3158
|
+
function isInternalURL(url) {
|
|
3159
|
+
return url.startsWith('internal://');
|
|
3160
|
+
}
|
|
3013
3161
|
//# sourceMappingURL=malloy.js.map
|
package/dist/runtime_types.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export type ModelURL = URL;
|
|
|
14
14
|
* A URL whose contents is a Malloy query.
|
|
15
15
|
*/
|
|
16
16
|
export type QueryURL = URL;
|
|
17
|
+
export type InvalidationKey = string | number | Date | null;
|
|
17
18
|
/**
|
|
18
19
|
* An object capable of reading the contents of a URL in some context.
|
|
19
20
|
*/
|
|
@@ -24,7 +25,11 @@ export interface URLReader {
|
|
|
24
25
|
* @param url The URL to read.
|
|
25
26
|
* @return A promise to the contents of the URL.
|
|
26
27
|
*/
|
|
27
|
-
readURL: (url: URL) => Promise<string
|
|
28
|
+
readURL: (url: URL) => Promise<string | {
|
|
29
|
+
contents: string;
|
|
30
|
+
invalidationKey?: InvalidationKey;
|
|
31
|
+
}>;
|
|
32
|
+
getInvalidationKey?: (url: URL) => Promise<InvalidationKey>;
|
|
28
33
|
}
|
|
29
34
|
export interface EventStream {
|
|
30
35
|
emit(id: string, data: any): void;
|