trellis 2.0.13 → 2.1.2
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/cli/index.js +1 -1
- package/dist/embeddings/index.js +1 -1
- package/dist/{index-7gvjxt27.js → index-2917tjd8.js} +1 -1
- package/package.json +2 -10
- package/dist/transformers.node-bx3q9d7k.js +0 -33130
- package/src/cli/index.ts +0 -3356
- package/src/core/agents/harness.ts +0 -380
- package/src/core/agents/index.ts +0 -18
- package/src/core/agents/types.ts +0 -90
- package/src/core/index.ts +0 -118
- package/src/core/kernel/middleware.ts +0 -44
- package/src/core/kernel/trellis-kernel.ts +0 -593
- package/src/core/ontology/builtins.ts +0 -248
- package/src/core/ontology/index.ts +0 -34
- package/src/core/ontology/registry.ts +0 -209
- package/src/core/ontology/types.ts +0 -124
- package/src/core/ontology/validator.ts +0 -382
- package/src/core/persist/backend.ts +0 -74
- package/src/core/persist/sqlite-backend.ts +0 -298
- package/src/core/plugins/index.ts +0 -17
- package/src/core/plugins/registry.ts +0 -322
- package/src/core/plugins/types.ts +0 -126
- package/src/core/query/datalog.ts +0 -188
- package/src/core/query/engine.ts +0 -370
- package/src/core/query/index.ts +0 -34
- package/src/core/query/parser.ts +0 -481
- package/src/core/query/types.ts +0 -200
- package/src/core/store/eav-store.ts +0 -467
- package/src/decisions/auto-capture.ts +0 -136
- package/src/decisions/hooks.ts +0 -163
- package/src/decisions/index.ts +0 -261
- package/src/decisions/types.ts +0 -103
- package/src/embeddings/auto-embed.ts +0 -248
- package/src/embeddings/chunker.ts +0 -327
- package/src/embeddings/index.ts +0 -48
- package/src/embeddings/model.ts +0 -112
- package/src/embeddings/search.ts +0 -305
- package/src/embeddings/store.ts +0 -313
- package/src/embeddings/types.ts +0 -92
- package/src/engine.ts +0 -1125
- package/src/garden/cluster.ts +0 -330
- package/src/garden/garden.ts +0 -306
- package/src/garden/index.ts +0 -29
- package/src/git/git-exporter.ts +0 -286
- package/src/git/git-importer.ts +0 -329
- package/src/git/git-reader.ts +0 -189
- package/src/git/index.ts +0 -22
- package/src/identity/governance.ts +0 -211
- package/src/identity/identity.ts +0 -224
- package/src/identity/index.ts +0 -30
- package/src/identity/signing-middleware.ts +0 -97
- package/src/index.ts +0 -29
- package/src/links/index.ts +0 -49
- package/src/links/lifecycle.ts +0 -400
- package/src/links/parser.ts +0 -484
- package/src/links/ref-index.ts +0 -186
- package/src/links/resolver.ts +0 -314
- package/src/links/types.ts +0 -108
- package/src/mcp/index.ts +0 -22
- package/src/mcp/server.ts +0 -1278
- package/src/semantic/csharp-parser.ts +0 -493
- package/src/semantic/go-parser.ts +0 -585
- package/src/semantic/index.ts +0 -34
- package/src/semantic/java-parser.ts +0 -456
- package/src/semantic/python-parser.ts +0 -659
- package/src/semantic/ruby-parser.ts +0 -446
- package/src/semantic/rust-parser.ts +0 -784
- package/src/semantic/semantic-merge.ts +0 -210
- package/src/semantic/ts-parser.ts +0 -681
- package/src/semantic/types.ts +0 -175
- package/src/sync/http-transport.ts +0 -144
- package/src/sync/index.ts +0 -43
- package/src/sync/memory-transport.ts +0 -66
- package/src/sync/multi-repo.ts +0 -200
- package/src/sync/reconciler.ts +0 -237
- package/src/sync/sync-engine.ts +0 -258
- package/src/sync/types.ts +0 -104
- package/src/sync/ws-transport.ts +0 -145
- package/src/ui/client.html +0 -695
- package/src/ui/server.ts +0 -419
- package/src/vcs/blob-store.ts +0 -124
- package/src/vcs/branch.ts +0 -150
- package/src/vcs/checkpoint.ts +0 -64
- package/src/vcs/decompose.ts +0 -469
- package/src/vcs/diff.ts +0 -409
- package/src/vcs/engine-context.ts +0 -26
- package/src/vcs/index.ts +0 -23
- package/src/vcs/issue.ts +0 -800
- package/src/vcs/merge.ts +0 -425
- package/src/vcs/milestone.ts +0 -124
- package/src/vcs/ops.ts +0 -59
- package/src/vcs/types.ts +0 -213
- package/src/vcs/vcs-middleware.ts +0 -81
- package/src/watcher/fs-watcher.ts +0 -255
- package/src/watcher/index.ts +0 -9
- package/src/watcher/ingestion.ts +0 -116
package/src/embeddings/model.ts
DELETED
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Embedding Model
|
|
3
|
-
*
|
|
4
|
-
* Lazy-loads @huggingface/transformers (v3+) with all-MiniLM-L6-v2 (384-dim).
|
|
5
|
-
* Falls back to @xenova/transformers (v2) if the new package is unavailable.
|
|
6
|
-
* Model is loaded once on first use and cached for subsequent calls.
|
|
7
|
-
*
|
|
8
|
-
* @see TRL-18
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import { EmbeddingModelConfig, DEFAULT_MODEL_CONFIG } from './types.js';
|
|
12
|
-
|
|
13
|
-
// ---------------------------------------------------------------------------
|
|
14
|
-
// Model singleton
|
|
15
|
-
// ---------------------------------------------------------------------------
|
|
16
|
-
|
|
17
|
-
let pipeline: any = null;
|
|
18
|
-
let loadPromise: Promise<any> | null = null;
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Dynamically import the transformers library.
|
|
22
|
-
* Tries @huggingface/transformers first (v3+), falls back to @xenova/transformers (v2).
|
|
23
|
-
*/
|
|
24
|
-
async function importTransformers(): Promise<{ pipeline: any }> {
|
|
25
|
-
try {
|
|
26
|
-
return await import('@huggingface/transformers' as string);
|
|
27
|
-
} catch {
|
|
28
|
-
try {
|
|
29
|
-
return await import('@xenova/transformers' as string);
|
|
30
|
-
} catch {
|
|
31
|
-
throw new Error(
|
|
32
|
-
'No transformers library found. Install @huggingface/transformers (recommended) or @xenova/transformers.',
|
|
33
|
-
);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Load the embedding model lazily. Returns the feature-extraction pipeline.
|
|
40
|
-
* Subsequent calls return the cached pipeline.
|
|
41
|
-
*/
|
|
42
|
-
export async function loadModel(
|
|
43
|
-
config: EmbeddingModelConfig = DEFAULT_MODEL_CONFIG,
|
|
44
|
-
): Promise<any> {
|
|
45
|
-
if (pipeline) return pipeline;
|
|
46
|
-
|
|
47
|
-
if (!loadPromise) {
|
|
48
|
-
loadPromise = (async () => {
|
|
49
|
-
const { pipeline: createPipeline } = await importTransformers();
|
|
50
|
-
const opts: Record<string, unknown> = {};
|
|
51
|
-
if (config.cacheDir) {
|
|
52
|
-
opts.cache_dir = config.cacheDir;
|
|
53
|
-
}
|
|
54
|
-
pipeline = await createPipeline(
|
|
55
|
-
'feature-extraction',
|
|
56
|
-
config.modelName,
|
|
57
|
-
opts,
|
|
58
|
-
);
|
|
59
|
-
return pipeline;
|
|
60
|
-
})();
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
return loadPromise;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Generate an embedding vector for the given text.
|
|
68
|
-
* Returns a Float32Array of length `config.dimension` (default: 384).
|
|
69
|
-
*/
|
|
70
|
-
export async function embed(
|
|
71
|
-
text: string,
|
|
72
|
-
config: EmbeddingModelConfig = DEFAULT_MODEL_CONFIG,
|
|
73
|
-
): Promise<Float32Array> {
|
|
74
|
-
const pipe = await loadModel(config);
|
|
75
|
-
const output = await pipe(text, { pooling: 'mean', normalize: true });
|
|
76
|
-
// output.data is a Float32Array of shape [1, dimension]
|
|
77
|
-
return new Float32Array(output.data);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Generate embeddings for multiple texts in a batch.
|
|
82
|
-
* More efficient than calling embed() individually.
|
|
83
|
-
*/
|
|
84
|
-
export async function embedBatch(
|
|
85
|
-
texts: string[],
|
|
86
|
-
config: EmbeddingModelConfig = DEFAULT_MODEL_CONFIG,
|
|
87
|
-
): Promise<Float32Array[]> {
|
|
88
|
-
if (texts.length === 0) return [];
|
|
89
|
-
|
|
90
|
-
const pipe = await loadModel(config);
|
|
91
|
-
const results: Float32Array[] = [];
|
|
92
|
-
|
|
93
|
-
// Process in batches of 32 to manage memory
|
|
94
|
-
const batchSize = 32;
|
|
95
|
-
for (let i = 0; i < texts.length; i += batchSize) {
|
|
96
|
-
const batch = texts.slice(i, i + batchSize);
|
|
97
|
-
for (const text of batch) {
|
|
98
|
-
const output = await pipe(text, { pooling: 'mean', normalize: true });
|
|
99
|
-
results.push(new Float32Array(output.data));
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
return results;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Reset the model singleton. Useful for testing.
|
|
108
|
-
*/
|
|
109
|
-
export function resetModel(): void {
|
|
110
|
-
pipeline = null;
|
|
111
|
-
loadPromise = null;
|
|
112
|
-
}
|
package/src/embeddings/search.ts
DELETED
|
@@ -1,305 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Semantic Search Integration
|
|
3
|
-
*
|
|
4
|
-
* Connects the TrellisVcsEngine to the embedding system.
|
|
5
|
-
* Provides reindex (full rebuild) and search (query → ranked results).
|
|
6
|
-
* The embedder function is pluggable for testing with mock vectors.
|
|
7
|
-
*
|
|
8
|
-
* @see TRL-20
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import { join } from 'path';
|
|
12
|
-
import { readFileSync, existsSync } from 'fs';
|
|
13
|
-
import { VectorStore } from './store.js';
|
|
14
|
-
import { embed } from './model.js';
|
|
15
|
-
import {
|
|
16
|
-
chunkIssue,
|
|
17
|
-
chunkMilestone,
|
|
18
|
-
chunkDecision,
|
|
19
|
-
chunkMarkdown,
|
|
20
|
-
chunkCodeEntities,
|
|
21
|
-
chunkFile,
|
|
22
|
-
} from './chunker.js';
|
|
23
|
-
import type {
|
|
24
|
-
ChunkMeta,
|
|
25
|
-
EmbeddingRecord,
|
|
26
|
-
SearchOptions,
|
|
27
|
-
SearchResult,
|
|
28
|
-
} from './types.js';
|
|
29
|
-
|
|
30
|
-
// ---------------------------------------------------------------------------
|
|
31
|
-
// Types
|
|
32
|
-
// ---------------------------------------------------------------------------
|
|
33
|
-
|
|
34
|
-
/** Minimal engine interface — avoids importing the full engine for testability */
|
|
35
|
-
export interface SearchableEngine {
|
|
36
|
-
getRootPath(): string;
|
|
37
|
-
trackedFiles(): Array<{ path: string; contentHash?: string }>;
|
|
38
|
-
listIssues(filters?: any): Array<{
|
|
39
|
-
id: string;
|
|
40
|
-
title?: string;
|
|
41
|
-
description?: string;
|
|
42
|
-
}>;
|
|
43
|
-
listMilestones(): Array<{ id: string; message?: string }>;
|
|
44
|
-
queryDecisions?(): Array<{
|
|
45
|
-
id: string;
|
|
46
|
-
toolName: string;
|
|
47
|
-
rationale?: string;
|
|
48
|
-
context?: string;
|
|
49
|
-
outputSummary?: string;
|
|
50
|
-
}>;
|
|
51
|
-
parseFile?(filePath: string): any;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/** Embedder function type — maps text → vector. Pluggable for testing. */
|
|
55
|
-
export type Embedder = (text: string) => Promise<Float32Array>;
|
|
56
|
-
|
|
57
|
-
// ---------------------------------------------------------------------------
|
|
58
|
-
// EmbeddingManager
|
|
59
|
-
// ---------------------------------------------------------------------------
|
|
60
|
-
|
|
61
|
-
export class EmbeddingManager {
|
|
62
|
-
private store: VectorStore;
|
|
63
|
-
private embedFn: Embedder;
|
|
64
|
-
|
|
65
|
-
constructor(dbPath: string, embedFn?: Embedder) {
|
|
66
|
-
this.store = new VectorStore(dbPath);
|
|
67
|
-
this.embedFn = embedFn ?? embed;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Full reindex: clear store, re-chunk all entities, embed, and insert.
|
|
72
|
-
*/
|
|
73
|
-
async reindex(engine: SearchableEngine): Promise<{ chunks: number }> {
|
|
74
|
-
this.store.clear();
|
|
75
|
-
|
|
76
|
-
const allChunks: ChunkMeta[] = [];
|
|
77
|
-
|
|
78
|
-
// 1. Issues
|
|
79
|
-
const issues = engine.listIssues();
|
|
80
|
-
for (const issue of issues) {
|
|
81
|
-
allChunks.push(...chunkIssue(issue));
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// 2. Milestones
|
|
85
|
-
const milestones = engine.listMilestones();
|
|
86
|
-
for (const ms of milestones) {
|
|
87
|
-
allChunks.push(...chunkMilestone(ms));
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// 3. Decisions
|
|
91
|
-
if (engine.queryDecisions) {
|
|
92
|
-
const decisions = engine.queryDecisions();
|
|
93
|
-
for (const dec of decisions) {
|
|
94
|
-
allChunks.push(...chunkDecision(dec));
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// 4. Files (markdown, summaries)
|
|
99
|
-
const rootPath = engine.getRootPath();
|
|
100
|
-
const trackedFiles = engine.trackedFiles();
|
|
101
|
-
for (const tf of trackedFiles) {
|
|
102
|
-
try {
|
|
103
|
-
const absPath = join(rootPath, tf.path);
|
|
104
|
-
if (!existsSync(absPath)) continue;
|
|
105
|
-
const content = readFileSync(absPath, 'utf-8');
|
|
106
|
-
allChunks.push(...chunkFile(tf.path, content));
|
|
107
|
-
} catch {}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// 5. Code entities (from parsed files)
|
|
111
|
-
if (engine.parseFile) {
|
|
112
|
-
for (const tf of trackedFiles) {
|
|
113
|
-
const ext = tf.path.split('.').pop()?.toLowerCase() ?? '';
|
|
114
|
-
if (
|
|
115
|
-
![
|
|
116
|
-
'ts',
|
|
117
|
-
'js',
|
|
118
|
-
'tsx',
|
|
119
|
-
'jsx',
|
|
120
|
-
'py',
|
|
121
|
-
'go',
|
|
122
|
-
'rs',
|
|
123
|
-
'rb',
|
|
124
|
-
'java',
|
|
125
|
-
'cs',
|
|
126
|
-
].includes(ext)
|
|
127
|
-
) {
|
|
128
|
-
continue;
|
|
129
|
-
}
|
|
130
|
-
try {
|
|
131
|
-
const parsed = engine.parseFile(tf.path);
|
|
132
|
-
if (parsed && Array.isArray(parsed.entities)) {
|
|
133
|
-
const declarations = parsed.entities.map((e: any) => ({
|
|
134
|
-
id: e.id ?? e.name,
|
|
135
|
-
name: e.name,
|
|
136
|
-
kind: e.kind,
|
|
137
|
-
signature: e.signature ?? e.rawText?.split('\n')[0] ?? '',
|
|
138
|
-
docComment: e.docComment,
|
|
139
|
-
}));
|
|
140
|
-
allChunks.push(...chunkCodeEntities(tf.path, declarations));
|
|
141
|
-
}
|
|
142
|
-
} catch {}
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
// Embed and insert all chunks
|
|
147
|
-
const records: EmbeddingRecord[] = [];
|
|
148
|
-
for (const chunk of allChunks) {
|
|
149
|
-
try {
|
|
150
|
-
const vector = await this.embedFn(chunk.content);
|
|
151
|
-
records.push({ ...chunk, embedding: vector });
|
|
152
|
-
} catch {}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
this.store.upsertBatch(records);
|
|
156
|
-
|
|
157
|
-
return { chunks: records.length };
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* Incrementally index a single file (on file change).
|
|
162
|
-
*/
|
|
163
|
-
async indexFile(
|
|
164
|
-
filePath: string,
|
|
165
|
-
content: string,
|
|
166
|
-
engine?: SearchableEngine,
|
|
167
|
-
): Promise<number> {
|
|
168
|
-
// Remove old chunks for this file
|
|
169
|
-
this.store.deleteByFile(filePath);
|
|
170
|
-
|
|
171
|
-
const chunks = chunkFile(filePath, content);
|
|
172
|
-
|
|
173
|
-
// Also index code entities if engine is available
|
|
174
|
-
if (engine?.parseFile) {
|
|
175
|
-
const ext = filePath.split('.').pop()?.toLowerCase() ?? '';
|
|
176
|
-
if (
|
|
177
|
-
[
|
|
178
|
-
'ts',
|
|
179
|
-
'js',
|
|
180
|
-
'tsx',
|
|
181
|
-
'jsx',
|
|
182
|
-
'py',
|
|
183
|
-
'go',
|
|
184
|
-
'rs',
|
|
185
|
-
'rb',
|
|
186
|
-
'java',
|
|
187
|
-
'cs',
|
|
188
|
-
].includes(ext)
|
|
189
|
-
) {
|
|
190
|
-
try {
|
|
191
|
-
const parsed = engine.parseFile(filePath);
|
|
192
|
-
if (parsed && Array.isArray(parsed.entities)) {
|
|
193
|
-
const declarations = parsed.entities.map((e: any) => ({
|
|
194
|
-
id: e.id ?? e.name,
|
|
195
|
-
name: e.name,
|
|
196
|
-
kind: e.kind,
|
|
197
|
-
signature: e.signature ?? e.rawText?.split('\n')[0] ?? '',
|
|
198
|
-
docComment: e.docComment,
|
|
199
|
-
}));
|
|
200
|
-
chunks.push(...chunkCodeEntities(filePath, declarations));
|
|
201
|
-
}
|
|
202
|
-
} catch {}
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
const records: EmbeddingRecord[] = [];
|
|
207
|
-
for (const chunk of chunks) {
|
|
208
|
-
try {
|
|
209
|
-
const vector = await this.embedFn(chunk.content);
|
|
210
|
-
records.push({ ...chunk, embedding: vector });
|
|
211
|
-
} catch {}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
if (records.length > 0) {
|
|
215
|
-
this.store.upsertBatch(records);
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
return records.length;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
/**
|
|
222
|
-
* Index an issue (on create/update).
|
|
223
|
-
*/
|
|
224
|
-
async indexIssue(issue: {
|
|
225
|
-
id: string;
|
|
226
|
-
title?: string;
|
|
227
|
-
description?: string;
|
|
228
|
-
}): Promise<number> {
|
|
229
|
-
this.store.deleteByEntity(`issue:${issue.id}`);
|
|
230
|
-
|
|
231
|
-
const chunks = chunkIssue(issue);
|
|
232
|
-
const records: EmbeddingRecord[] = [];
|
|
233
|
-
|
|
234
|
-
for (const chunk of chunks) {
|
|
235
|
-
try {
|
|
236
|
-
const vector = await this.embedFn(chunk.content);
|
|
237
|
-
records.push({ ...chunk, embedding: vector });
|
|
238
|
-
} catch {}
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
if (records.length > 0) {
|
|
242
|
-
this.store.upsertBatch(records);
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
return records.length;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
/**
|
|
249
|
-
* Index a milestone (on create).
|
|
250
|
-
*/
|
|
251
|
-
async indexMilestone(milestone: {
|
|
252
|
-
id: string;
|
|
253
|
-
message?: string;
|
|
254
|
-
}): Promise<number> {
|
|
255
|
-
this.store.deleteByEntity(`milestone:${milestone.id}`);
|
|
256
|
-
|
|
257
|
-
const chunks = chunkMilestone(milestone);
|
|
258
|
-
const records: EmbeddingRecord[] = [];
|
|
259
|
-
|
|
260
|
-
for (const chunk of chunks) {
|
|
261
|
-
try {
|
|
262
|
-
const vector = await this.embedFn(chunk.content);
|
|
263
|
-
records.push({ ...chunk, embedding: vector });
|
|
264
|
-
} catch {}
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
if (records.length > 0) {
|
|
268
|
-
this.store.upsertBatch(records);
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
return records.length;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
/**
|
|
275
|
-
* Semantic search: embed query → vector search → ranked results.
|
|
276
|
-
*/
|
|
277
|
-
async search(query: string, opts?: SearchOptions): Promise<SearchResult[]> {
|
|
278
|
-
const queryVector = await this.embedFn(query);
|
|
279
|
-
return this.store.search(queryVector, opts);
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
/**
|
|
283
|
-
* Remove all data for a file.
|
|
284
|
-
*/
|
|
285
|
-
removeFile(filePath: string): void {
|
|
286
|
-
this.store.deleteByFile(filePath);
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
/**
|
|
290
|
-
* Get store statistics.
|
|
291
|
-
*/
|
|
292
|
-
stats(): { total: number; byType: Record<string, number> } {
|
|
293
|
-
return {
|
|
294
|
-
total: this.store.count(),
|
|
295
|
-
byType: this.store.countByType(),
|
|
296
|
-
};
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
/**
|
|
300
|
-
* Close the store.
|
|
301
|
-
*/
|
|
302
|
-
close(): void {
|
|
303
|
-
this.store.close();
|
|
304
|
-
}
|
|
305
|
-
}
|