@verdant-web/store 5.4.4 → 5.5.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/dist/bundle/index.js +8 -8
- package/dist/bundle/index.js.map +4 -4
- package/dist/esm/__tests__/entities.test.js +3 -3
- package/dist/esm/__tests__/entities.test.js.map +1 -1
- package/dist/esm/entities/Entity.d.ts +2 -3
- package/dist/esm/entities/Entity.js +37 -17
- package/dist/esm/entities/Entity.js.map +1 -1
- package/dist/esm/entities/EntityStore.js +1 -1
- package/dist/esm/entities/EntityStore.js.map +1 -1
- package/dist/esm/files/EntityFile.d.ts +22 -7
- package/dist/esm/files/EntityFile.js +30 -6
- package/dist/esm/files/EntityFile.js.map +1 -1
- package/dist/esm/files/FileManager.d.ts +5 -4
- package/dist/esm/files/FileManager.js +35 -16
- package/dist/esm/files/FileManager.js.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/entities.test.ts +3 -3
- package/src/entities/Entity.ts +30 -8
- package/src/entities/EntityStore.ts +1 -1
- package/src/files/EntityFile.ts +52 -10
- package/src/files/FileManager.ts +45 -20
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
var _a, _b;
|
|
2
|
-
import { EventSubscriber } from '@verdant-web/common';
|
|
2
|
+
import { EventSubscriber, } from '@verdant-web/common';
|
|
3
3
|
export const UPDATE = Symbol('entity-file-update');
|
|
4
4
|
export const MARK_FAILED = Symbol('entity-file-mark-failed');
|
|
5
|
-
// this one goes on Entity
|
|
6
|
-
export const CHILD_FILE_CHANGED = Symbol('child-file-changed');
|
|
7
5
|
/**
|
|
8
6
|
* Provides a consistent interface for files used in an app via
|
|
9
7
|
* Entity access.
|
|
10
8
|
*/
|
|
11
9
|
export class EntityFile extends EventSubscriber {
|
|
12
|
-
constructor(id, { downloadRemote = false, ctx,
|
|
10
|
+
constructor(id, { downloadRemote = false, ctx, fileContext, }) {
|
|
11
|
+
var _c, _d;
|
|
13
12
|
super();
|
|
14
13
|
this.id = id;
|
|
15
14
|
// cached object URL for a local blob file, if applicable
|
|
@@ -19,7 +18,26 @@ export class EntityFile extends EventSubscriber {
|
|
|
19
18
|
this._failed = false;
|
|
20
19
|
this._downloadRemote = false;
|
|
21
20
|
this._uploaded = false;
|
|
21
|
+
this._alt = null;
|
|
22
22
|
this.unsubscribes = [];
|
|
23
|
+
this.setAlt = (alt) => {
|
|
24
|
+
var _c;
|
|
25
|
+
const file = this.fileContext.getFileRef();
|
|
26
|
+
if (!file || file.id !== this.id) {
|
|
27
|
+
throw new Error('Cannot set alt text on a file which is no longer present');
|
|
28
|
+
}
|
|
29
|
+
if (((_c = file.alt) !== null && _c !== void 0 ? _c : null) === alt)
|
|
30
|
+
return;
|
|
31
|
+
this.fileContext.applyFileRef(Object.assign(Object.assign({}, file), { alt }));
|
|
32
|
+
};
|
|
33
|
+
this.onContextChange = () => {
|
|
34
|
+
var _c, _d;
|
|
35
|
+
const nextAlt = (_d = (_c = this.fileContext.getFileRef()) === null || _c === void 0 ? void 0 : _c.alt) !== null && _d !== void 0 ? _d : null;
|
|
36
|
+
if (nextAlt !== this._alt) {
|
|
37
|
+
this._alt = nextAlt;
|
|
38
|
+
this.emitChange();
|
|
39
|
+
}
|
|
40
|
+
};
|
|
23
41
|
this[_a] = (fileData) => {
|
|
24
42
|
this.ctx.log('debug', 'EntityFile updated', this.id, fileData);
|
|
25
43
|
this._loading = false;
|
|
@@ -55,8 +73,10 @@ export class EntityFile extends EventSubscriber {
|
|
|
55
73
|
this.dispose();
|
|
56
74
|
};
|
|
57
75
|
this.ctx = ctx;
|
|
58
|
-
this.
|
|
76
|
+
this.fileContext = fileContext;
|
|
59
77
|
this._downloadRemote = downloadRemote;
|
|
78
|
+
this._alt = (_d = (_c = fileContext.getFileRef()) === null || _c === void 0 ? void 0 : _c.alt) !== null && _d !== void 0 ? _d : null;
|
|
79
|
+
this.unsubscribes.push(fileContext.subscribe(this.onContextChange));
|
|
60
80
|
this.unsubscribes.push(this.ctx.internalEvents.subscribe(`fileUploaded:${id}`, this.onUploaded));
|
|
61
81
|
}
|
|
62
82
|
get downloadRemote() {
|
|
@@ -72,8 +92,11 @@ export class EntityFile extends EventSubscriber {
|
|
|
72
92
|
get error() {
|
|
73
93
|
return this._failedReason || null;
|
|
74
94
|
}
|
|
95
|
+
get alt() {
|
|
96
|
+
return this._alt;
|
|
97
|
+
}
|
|
75
98
|
emitChange() {
|
|
76
|
-
this.
|
|
99
|
+
this.fileContext.onChange();
|
|
77
100
|
this.emit('change');
|
|
78
101
|
}
|
|
79
102
|
get url() {
|
|
@@ -109,6 +132,7 @@ export class EntityFile extends EventSubscriber {
|
|
|
109
132
|
remote: (_h = (_g = this._fileData) === null || _g === void 0 ? void 0 : _g.remote) !== null && _h !== void 0 ? _h : false,
|
|
110
133
|
type: (_j = this.type) !== null && _j !== void 0 ? _j : '',
|
|
111
134
|
file: (_k = this._fileData) === null || _k === void 0 ? void 0 : _k.file,
|
|
135
|
+
alt: this.alt,
|
|
112
136
|
};
|
|
113
137
|
}
|
|
114
138
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EntityFile.js","sourceRoot":"","sources":["../../../src/files/EntityFile.ts"],"names":[],"mappings":";AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"EntityFile.js","sourceRoot":"","sources":["../../../src/files/EntityFile.ts"],"names":[],"mappings":";AAAA,OAAO,EACN,eAAe,GAKf,MAAM,qBAAqB,CAAC;AAO7B,MAAM,CAAC,MAAM,MAAM,GAAG,MAAM,CAAC,oBAAoB,CAAC,CAAC;AACnD,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC,yBAAyB,CAAC,CAAC;AAqB7D;;;GAGG;AACH,MAAM,OAAO,UAAW,SAAQ,eAAiC;IAchE,YACiB,EAAU,EAC1B,EACC,cAAc,GAAG,KAAK,EACtB,GAAG,EACH,WAAW,GAKX;;QAED,KAAK,EAAE,CAAC;QAXQ,OAAE,GAAF,EAAE,CAAQ;QAd3B,yDAAyD;QACjD,eAAU,GAAkB,IAAI,CAAC;QACjC,cAAS,GAAoB,IAAI,CAAC;QAClC,aAAQ,GAAG,IAAI,CAAC;QAChB,YAAO,GAAG,KAAK,CAAC;QAEhB,oBAAe,GAAG,KAAK,CAAC;QACxB,cAAS,GAAG,KAAK,CAAC;QAClB,SAAI,GAAkB,IAAI,CAAC;QAE3B,iBAAY,GAAmB,EAAE,CAAC;QA2C1C,WAAM,GAAG,CAAC,GAAkB,EAAE,EAAE;;YAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,CAAC;YAC3C,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,EAAE,CAAC;gBAClC,MAAM,IAAI,KAAK,CACd,0DAA0D,CAC1D,CAAC;YACH,CAAC;YACD,IAAI,CAAC,MAAA,IAAI,CAAC,GAAG,mCAAI,IAAI,CAAC,KAAK,GAAG;gBAAE,OAAO;YACvC,IAAI,CAAC,WAAW,CAAC,YAAY,iCAAM,IAAI,KAAE,GAAG,IAAG,CAAC;QACjD,CAAC,CAAC;QAEM,oBAAe,GAAG,GAAG,EAAE;;YAC9B,MAAM,OAAO,GAAG,MAAA,MAAA,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,0CAAE,GAAG,mCAAI,IAAI,CAAC;YAC3D,IAAI,OAAO,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;gBAC3B,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC;gBACpB,IAAI,CAAC,UAAU,EAAE,CAAC;YACnB,CAAC;QACF,CAAC,CAAC;QAOF,QAAQ,GAAG,CAAC,QAAkB,EAAE,EAAE;YACjC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,oBAAoB,EAAE,IAAI,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;YAC/D,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;YACtB,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;YACrB,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;YAC1B,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;gBACnB,IAAI,IAAI,CAAC,UAAU,IAAI,iBAAiB,IAAI,GAAG,EAAE,CAAC;oBACjD,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;gBACtC,CAAC;gBACD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,8BAA8B,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;gBAC/D,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YACtD,CAAC;YACD,IAAI,CAAC,UAAU,EAAE,CAAC;QACnB,CAAC,CAAC;QAEF,QAAa,GAAG,CAAC,MAAe,EAAE,EAAE;YACnC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YACpB,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC;YAC5B,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;YACtB,IAAI,CAAC,UAAU,EAAE,CAAC;QACnB,CAAC,CAAC;QAEM,eAAU,GAAG,CAAC,IAAc,EAAE,EAAE;;YACvC,gDAAgD;YAChD,MAAA,IAAI,CAAC,SAAS,oCAAd,IAAI,CAAC,SAAS,GAAK,IAAI,EAAC;YACxB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;YACtB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,sBAAsB,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YACvE,IAAI,CAAC,UAAU,EAAE,CAAC;QACnB,CAAC,CAAC;QA0BF,YAAO,GAAG,GAAG,EAAE;YACd,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBACrB,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACtC,CAAC;YACD,IAAI,CAAC,OAAO,EAAE,CAAC;QAChB,CAAC,CAAC;QA9GD,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,eAAe,GAAG,cAAc,CAAC;QACtC,IAAI,CAAC,IAAI,GAAG,MAAA,MAAA,WAAW,CAAC,UAAU,EAAE,0CAAE,GAAG,mCAAI,IAAI,CAAC;QAClD,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;QAEpE,IAAI,CAAC,YAAY,CAAC,IAAI,CACrB,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,SAAS,CAAC,gBAAgB,EAAE,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CACxE,CAAC;IACH,CAAC;IAED,IAAI,cAAc;QACjB,OAAO,IAAI,CAAC,eAAe,CAAC;IAC7B,CAAC;IACD,IAAI,MAAM;QACT,OAAO,IAAI,CAAC;IACb,CAAC;IACD,IAAI,UAAU;;QACb,OAAO,IAAI,CAAC,SAAS,KAAI,MAAA,IAAI,CAAC,SAAS,0CAAE,MAAM,CAAA,IAAI,KAAK,CAAC;IAC1D,CAAC;IACD,IAAI,KAAK;QACR,OAAO,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC;IACnC,CAAC;IACD,IAAI,GAAG;QACN,OAAO,IAAI,CAAC,IAAI,CAAC;IAClB,CAAC;IAqBO,UAAU;QACjB,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC;QAC5B,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACrB,CAAC;IAgCD,IAAI,GAAG;;QACN,qCAAqC;QACrC,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC;QAC9B,IAAI,IAAI,CAAC,UAAU;YAAE,OAAO,IAAI,CAAC,UAAU,CAAC;QAC5C,4BAA4B;QAC5B,OAAO,MAAA,MAAA,IAAI,CAAC,SAAS,0CAAE,GAAG,mCAAI,IAAI,CAAC;IACpC,CAAC;IAED,IAAI,IAAI;;QACP,OAAO,MAAA,MAAA,IAAI,CAAC,SAAS,0CAAE,IAAI,mCAAI,IAAI,CAAC;IACrC,CAAC;IAED,IAAI,IAAI;;QACP,OAAO,MAAA,MAAA,IAAI,CAAC,SAAS,0CAAE,IAAI,mCAAI,IAAI,CAAC;IACrC,CAAC;IAED,IAAI,OAAO;QACV,OAAO,IAAI,CAAC,QAAQ,CAAC;IACtB,CAAC;IAED,IAAI,MAAM;QACT,OAAO,IAAI,CAAC,OAAO,CAAC;IACrB,CAAC;IASD,WAAW;;QACV,OAAO;YACN,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,GAAG,EAAE,MAAA,MAAA,MAAA,IAAI,CAAC,SAAS,0CAAE,GAAG,mCAAI,IAAI,CAAC,UAAU,mCAAI,SAAS;YACxD,IAAI,EAAE,MAAA,IAAI,CAAC,IAAI,mCAAI,cAAc;YACjC,MAAM,EAAE,MAAA,MAAA,IAAI,CAAC,SAAS,0CAAE,MAAM,mCAAI,KAAK;YACvC,IAAI,EAAE,MAAA,IAAI,CAAC,IAAI,mCAAI,EAAE;YACrB,IAAI,EAAE,MAAA,IAAI,CAAC,SAAS,0CAAE,IAAI;YAC1B,GAAG,EAAE,IAAI,CAAC,GAAG;SACb,CAAC;IACH,CAAC;CACD;KAxEC,MAAM,OAeN,WAAW"}
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { FileData } from '@verdant-web/common';
|
|
2
2
|
import { Context } from '../context/context.js';
|
|
3
|
-
import { Entity } from '../entities/Entity.js';
|
|
4
3
|
import { Disposable } from '../internal.js';
|
|
5
4
|
import { Sync } from '../sync/Sync.js';
|
|
6
|
-
import { EntityFile } from './EntityFile.js';
|
|
5
|
+
import { EntityFile, EntityFileContext } from './EntityFile.js';
|
|
7
6
|
export declare class FileManager extends Disposable {
|
|
8
7
|
private sync;
|
|
9
8
|
private context;
|
|
10
9
|
private cache;
|
|
10
|
+
private fileData;
|
|
11
11
|
constructor({ sync, context }: {
|
|
12
12
|
sync: Sync;
|
|
13
13
|
context: Context;
|
|
14
14
|
});
|
|
15
|
-
add: (file: FileData
|
|
15
|
+
add: (file: FileData) => Promise<void>;
|
|
16
16
|
/**
|
|
17
17
|
* Immediately returns an EntityFile to use, then either loads
|
|
18
18
|
* the file from cache, local database, or the server.
|
|
@@ -20,8 +20,9 @@ export declare class FileManager extends Disposable {
|
|
|
20
20
|
get: (id: string, options: {
|
|
21
21
|
downloadRemote?: boolean;
|
|
22
22
|
ctx: Context;
|
|
23
|
-
|
|
23
|
+
fileContext: EntityFileContext;
|
|
24
24
|
}) => EntityFile;
|
|
25
|
+
private updateFileData;
|
|
25
26
|
private load;
|
|
26
27
|
private onFileUploaded;
|
|
27
28
|
}
|
|
@@ -1,44 +1,63 @@
|
|
|
1
1
|
import { Disposable } from '../internal.js';
|
|
2
|
-
import { EntityFile, MARK_FAILED, UPDATE } from './EntityFile.js';
|
|
2
|
+
import { EntityFile, MARK_FAILED, UPDATE, } from './EntityFile.js';
|
|
3
3
|
export class FileManager extends Disposable {
|
|
4
4
|
constructor({ sync, context }) {
|
|
5
5
|
super();
|
|
6
6
|
this.cache = new Map();
|
|
7
|
-
this.
|
|
8
|
-
|
|
9
|
-
let entityFile = this.cache.get(file.id);
|
|
10
|
-
if (!entityFile) {
|
|
11
|
-
entityFile = new EntityFile(file.id, { ctx: this.context, parent });
|
|
12
|
-
this.cache.set(file.id, entityFile);
|
|
13
|
-
}
|
|
7
|
+
this.fileData = new Map();
|
|
8
|
+
this.add = async (file) => {
|
|
14
9
|
if (!file.remote) {
|
|
15
10
|
// immediately update local files.
|
|
16
|
-
|
|
11
|
+
this.updateFileData(file);
|
|
17
12
|
}
|
|
18
13
|
// this will download any original remote file and trigger a re-upload to the
|
|
19
14
|
// new file's identity, in addition to storing it on disk
|
|
20
15
|
const processedFile = await (await this.context.files).add(file, { cloneRemote: true });
|
|
21
|
-
|
|
16
|
+
this.updateFileData(processedFile);
|
|
22
17
|
};
|
|
23
18
|
/**
|
|
24
19
|
* Immediately returns an EntityFile to use, then either loads
|
|
25
20
|
* the file from cache, local database, or the server.
|
|
26
21
|
*/
|
|
27
22
|
this.get = (id, options) => {
|
|
28
|
-
|
|
29
|
-
|
|
23
|
+
var _a, _b;
|
|
24
|
+
const cacheKey = `${options.fileContext.oid}:${String(options.fileContext.key)}:${id}`;
|
|
25
|
+
const cachedFile = (_a = this.cache.get(cacheKey)) === null || _a === void 0 ? void 0 : _a.deref();
|
|
26
|
+
if (cachedFile) {
|
|
27
|
+
return cachedFile;
|
|
30
28
|
}
|
|
29
|
+
this.cache.delete(cacheKey);
|
|
31
30
|
const file = new EntityFile(id, options);
|
|
32
|
-
this.cache.set(
|
|
33
|
-
this.
|
|
31
|
+
this.cache.set(cacheKey, this.context.weakRef(file));
|
|
32
|
+
const data = (_b = this.fileData.get(id)) === null || _b === void 0 ? void 0 : _b.deref();
|
|
33
|
+
if (data) {
|
|
34
|
+
file[UPDATE](data);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
this.fileData.delete(id);
|
|
38
|
+
this.load(file);
|
|
39
|
+
}
|
|
34
40
|
return file;
|
|
35
41
|
};
|
|
42
|
+
this.updateFileData = (data) => {
|
|
43
|
+
this.fileData.set(data.id, this.context.weakRef(data));
|
|
44
|
+
for (const [key, fileRef] of this.cache) {
|
|
45
|
+
const file = fileRef.deref();
|
|
46
|
+
if (!file) {
|
|
47
|
+
this.cache.delete(key);
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (file.id === data.id) {
|
|
51
|
+
file[UPDATE](data);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
};
|
|
36
55
|
this.load = async (file) => {
|
|
37
56
|
var _a;
|
|
38
57
|
const fileData = await (await this.context.files).get(file.id);
|
|
39
58
|
// immediately apply any file data we have
|
|
40
59
|
if (fileData) {
|
|
41
|
-
|
|
60
|
+
this.updateFileData(fileData);
|
|
42
61
|
}
|
|
43
62
|
if (!(fileData === null || fileData === void 0 ? void 0 : fileData.url) && (!fileData || fileData.remote)) {
|
|
44
63
|
// maybe we don't have it yet, it might be on the server still.
|
|
@@ -59,7 +78,7 @@ export class FileManager extends Disposable {
|
|
|
59
78
|
// avoid overwriting local values except for url
|
|
60
79
|
const copyWithUrl = Object.assign(Object.assign(Object.assign({}, result.data), fileData), { url: result.data.url });
|
|
61
80
|
await (await this.context.files).update(copyWithUrl);
|
|
62
|
-
|
|
81
|
+
this.updateFileData(result.data);
|
|
63
82
|
}
|
|
64
83
|
else {
|
|
65
84
|
this.context.log('error', 'Failed to load file', result);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileManager.js","sourceRoot":"","sources":["../../../src/files/FileManager.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"FileManager.js","sourceRoot":"","sources":["../../../src/files/FileManager.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@verdant-web/store",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.5.0",
|
|
4
4
|
"access": "public",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/esm/index.js",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"jszip": "^3.10.1",
|
|
40
40
|
"jwt-decode": "^3.1.2",
|
|
41
41
|
"weak-event": "^2.0.5",
|
|
42
|
-
"@verdant-web/common": "3.2.
|
|
42
|
+
"@verdant-web/common": "3.2.2"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@types/node": "20.10.5",
|
|
@@ -583,9 +583,9 @@ describe('entities', () => {
|
|
|
583
583
|
|
|
584
584
|
fileList.moveItem(file1Ref, 2);
|
|
585
585
|
|
|
586
|
-
expect(fileList.get(0)).toBe(file2Ref);
|
|
587
|
-
expect(fileList.get(1)).toBe(file3Ref);
|
|
588
|
-
expect(fileList.get(2)).toBe(file1Ref);
|
|
586
|
+
expect(fileList.get(0).uid).toBe(file2Ref.uid);
|
|
587
|
+
expect(fileList.get(1).uid).toBe(file3Ref.uid);
|
|
588
|
+
expect(fileList.get(2).uid).toBe(file1Ref.uid);
|
|
589
589
|
});
|
|
590
590
|
|
|
591
591
|
it('should return nullish for missing map items', async () => {
|
package/src/entities/Entity.ts
CHANGED
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
validateEntityField,
|
|
28
28
|
} from '@verdant-web/common';
|
|
29
29
|
import { Context } from '../context/context.js';
|
|
30
|
-
import {
|
|
30
|
+
import { EntityFileContext } from '../files/EntityFile.js';
|
|
31
31
|
import { FileManager } from '../files/FileManager.js';
|
|
32
32
|
import { processValueFiles } from '../files/utils.js';
|
|
33
33
|
import { ClientWithCollections, EntityFile } from '../index.js';
|
|
@@ -751,16 +751,38 @@ export class Entity<
|
|
|
751
751
|
this.emit('changeDeep', target, ev);
|
|
752
752
|
this.parent?.deepChange(target, ev);
|
|
753
753
|
};
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
754
|
+
private createFileContext = (key: any): EntityFileContext => ({
|
|
755
|
+
oid: this.oid,
|
|
756
|
+
key,
|
|
757
|
+
getFileRef: () => {
|
|
758
|
+
const file = this.rawView?.[key];
|
|
759
|
+
return isFileRef(file) ? file : null;
|
|
760
|
+
},
|
|
761
|
+
applyFileRef: (file) => {
|
|
762
|
+
if (this.readonlyKeys.includes(key as string)) {
|
|
763
|
+
throw new Error(`Cannot set readonly key ${key.toString()}`);
|
|
764
|
+
}
|
|
765
|
+
this.addPendingOperations(
|
|
766
|
+
this.isList
|
|
767
|
+
? this.patchCreator.createListSet(this.oid, key, file)
|
|
768
|
+
: this.patchCreator.createSet(this.oid, key, file),
|
|
769
|
+
);
|
|
770
|
+
},
|
|
771
|
+
subscribe: (callback) => this.subscribe('change', callback),
|
|
772
|
+
onChange: () => this.deepChange(this, { isLocal: false, oid: this.oid }),
|
|
773
|
+
});
|
|
758
774
|
|
|
759
775
|
private getChild = (key: any, oid: ObjectIdentifier) => {
|
|
760
776
|
const schema = getChildFieldSchema(this.schema, key);
|
|
761
777
|
if (!schema) {
|
|
778
|
+
let schemaString = '';
|
|
779
|
+
try {
|
|
780
|
+
schemaString = JSON.stringify(this.schema);
|
|
781
|
+
} catch {
|
|
782
|
+
schemaString = '<unable to stringify schema>';
|
|
783
|
+
}
|
|
762
784
|
throw new Error(
|
|
763
|
-
`No schema for key ${String(key)} in ${
|
|
785
|
+
`No schema for key ${String(key)} in ${schemaString} (${this.oid})`,
|
|
764
786
|
);
|
|
765
787
|
}
|
|
766
788
|
return this.entityFamily.get({
|
|
@@ -828,7 +850,7 @@ export class Entity<
|
|
|
828
850
|
const file = this.files.get(child.id, {
|
|
829
851
|
downloadRemote: !!fieldSchema.downloadRemote,
|
|
830
852
|
ctx: this.ctx,
|
|
831
|
-
|
|
853
|
+
fileContext: this.createFileContext(key),
|
|
832
854
|
});
|
|
833
855
|
|
|
834
856
|
return file as KeyValue[Key];
|
|
@@ -1013,7 +1035,7 @@ export class Entity<
|
|
|
1013
1035
|
});
|
|
1014
1036
|
}
|
|
1015
1037
|
}
|
|
1016
|
-
return processValueFiles(value, (file) => this.files.add(file
|
|
1038
|
+
return processValueFiles(value, (file) => this.files.add(file));
|
|
1017
1039
|
};
|
|
1018
1040
|
|
|
1019
1041
|
private getDeleteMode = (key: any) => {
|
package/src/files/EntityFile.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
EventSubscriber,
|
|
3
|
+
FileData,
|
|
4
|
+
FileRef,
|
|
5
|
+
ObjectIdentifier,
|
|
6
|
+
PropertyName,
|
|
7
|
+
} from '@verdant-web/common';
|
|
2
8
|
import { Context } from '../context/context.js';
|
|
3
|
-
import { Entity } from '../entities/Entity.js';
|
|
4
9
|
|
|
5
10
|
export type EntityFileEvents = {
|
|
6
11
|
change: () => void;
|
|
@@ -9,12 +14,23 @@ export type EntityFileEvents = {
|
|
|
9
14
|
export const UPDATE = Symbol('entity-file-update');
|
|
10
15
|
export const MARK_FAILED = Symbol('entity-file-mark-failed');
|
|
11
16
|
|
|
12
|
-
|
|
13
|
-
|
|
17
|
+
export interface EntityFileContext {
|
|
18
|
+
readonly oid: ObjectIdentifier;
|
|
19
|
+
readonly key: PropertyName;
|
|
20
|
+
getFileRef(): FileRef | null;
|
|
21
|
+
applyFileRef(file: FileRef): void;
|
|
22
|
+
subscribe(callback: () => void): () => void;
|
|
23
|
+
onChange(): void;
|
|
24
|
+
}
|
|
14
25
|
|
|
15
26
|
export type EntityFileSnapshot = {
|
|
16
27
|
id: string;
|
|
17
28
|
url?: string | null;
|
|
29
|
+
name: string;
|
|
30
|
+
remote: boolean;
|
|
31
|
+
type: string;
|
|
32
|
+
file?: Blob | null;
|
|
33
|
+
alt: string | null;
|
|
18
34
|
};
|
|
19
35
|
|
|
20
36
|
/**
|
|
@@ -30,26 +46,29 @@ export class EntityFile extends EventSubscriber<EntityFileEvents> {
|
|
|
30
46
|
private _failedReason: string | undefined;
|
|
31
47
|
private _downloadRemote = false;
|
|
32
48
|
private _uploaded = false;
|
|
49
|
+
private _alt: string | null = null;
|
|
33
50
|
private ctx: Context;
|
|
34
51
|
private unsubscribes: (() => void)[] = [];
|
|
35
|
-
private
|
|
52
|
+
private fileContext: EntityFileContext;
|
|
36
53
|
|
|
37
54
|
constructor(
|
|
38
55
|
public readonly id: string,
|
|
39
56
|
{
|
|
40
57
|
downloadRemote = false,
|
|
41
58
|
ctx,
|
|
42
|
-
|
|
59
|
+
fileContext,
|
|
43
60
|
}: {
|
|
44
61
|
downloadRemote?: boolean;
|
|
45
62
|
ctx: Context;
|
|
46
|
-
|
|
63
|
+
fileContext: EntityFileContext;
|
|
47
64
|
},
|
|
48
65
|
) {
|
|
49
66
|
super();
|
|
50
67
|
this.ctx = ctx;
|
|
51
|
-
this.
|
|
68
|
+
this.fileContext = fileContext;
|
|
52
69
|
this._downloadRemote = downloadRemote;
|
|
70
|
+
this._alt = fileContext.getFileRef()?.alt ?? null;
|
|
71
|
+
this.unsubscribes.push(fileContext.subscribe(this.onContextChange));
|
|
53
72
|
|
|
54
73
|
this.unsubscribes.push(
|
|
55
74
|
this.ctx.internalEvents.subscribe(`fileUploaded:${id}`, this.onUploaded),
|
|
@@ -68,9 +87,31 @@ export class EntityFile extends EventSubscriber<EntityFileEvents> {
|
|
|
68
87
|
get error() {
|
|
69
88
|
return this._failedReason || null;
|
|
70
89
|
}
|
|
90
|
+
get alt() {
|
|
91
|
+
return this._alt;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
setAlt = (alt: string | null) => {
|
|
95
|
+
const file = this.fileContext.getFileRef();
|
|
96
|
+
if (!file || file.id !== this.id) {
|
|
97
|
+
throw new Error(
|
|
98
|
+
'Cannot set alt text on a file which is no longer present',
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
if ((file.alt ?? null) === alt) return;
|
|
102
|
+
this.fileContext.applyFileRef({ ...file, alt });
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
private onContextChange = () => {
|
|
106
|
+
const nextAlt = this.fileContext.getFileRef()?.alt ?? null;
|
|
107
|
+
if (nextAlt !== this._alt) {
|
|
108
|
+
this._alt = nextAlt;
|
|
109
|
+
this.emitChange();
|
|
110
|
+
}
|
|
111
|
+
};
|
|
71
112
|
|
|
72
113
|
private emitChange() {
|
|
73
|
-
this.
|
|
114
|
+
this.fileContext.onChange();
|
|
74
115
|
this.emit('change');
|
|
75
116
|
}
|
|
76
117
|
|
|
@@ -135,7 +176,7 @@ export class EntityFile extends EventSubscriber<EntityFileEvents> {
|
|
|
135
176
|
this.dispose();
|
|
136
177
|
};
|
|
137
178
|
|
|
138
|
-
getSnapshot():
|
|
179
|
+
getSnapshot(): EntityFileSnapshot {
|
|
139
180
|
return {
|
|
140
181
|
id: this.id,
|
|
141
182
|
url: this._fileData?.url ?? this._objectUrl ?? undefined,
|
|
@@ -143,6 +184,7 @@ export class EntityFile extends EventSubscriber<EntityFileEvents> {
|
|
|
143
184
|
remote: this._fileData?.remote ?? false,
|
|
144
185
|
type: this.type ?? '',
|
|
145
186
|
file: this._fileData?.file,
|
|
187
|
+
alt: this.alt,
|
|
146
188
|
};
|
|
147
189
|
}
|
|
148
190
|
}
|
package/src/files/FileManager.ts
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
import { FileData } from '@verdant-web/common';
|
|
2
2
|
import { Context } from '../context/context.js';
|
|
3
|
-
import { Entity } from '../entities/Entity.js';
|
|
4
3
|
import { Disposable } from '../internal.js';
|
|
5
4
|
import { Sync } from '../sync/Sync.js';
|
|
6
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
EntityFile,
|
|
7
|
+
EntityFileContext,
|
|
8
|
+
MARK_FAILED,
|
|
9
|
+
UPDATE,
|
|
10
|
+
} from './EntityFile.js';
|
|
7
11
|
|
|
8
12
|
export class FileManager extends Disposable {
|
|
9
13
|
private sync;
|
|
10
14
|
private context;
|
|
11
15
|
|
|
12
|
-
private cache = new Map<string, EntityFile
|
|
16
|
+
private cache = new Map<string, WeakRef<EntityFile>>();
|
|
17
|
+
private fileData = new Map<string, WeakRef<FileData>>();
|
|
13
18
|
|
|
14
19
|
constructor({ sync, context }: { sync: Sync; context: Context }) {
|
|
15
20
|
super();
|
|
@@ -23,24 +28,17 @@ export class FileManager extends Disposable {
|
|
|
23
28
|
);
|
|
24
29
|
}
|
|
25
30
|
|
|
26
|
-
add = async (file: FileData
|
|
27
|
-
// immediately cache the file
|
|
28
|
-
let entityFile = this.cache.get(file.id);
|
|
29
|
-
if (!entityFile) {
|
|
30
|
-
entityFile = new EntityFile(file.id, { ctx: this.context, parent });
|
|
31
|
-
this.cache.set(file.id, entityFile);
|
|
32
|
-
}
|
|
33
|
-
|
|
31
|
+
add = async (file: FileData) => {
|
|
34
32
|
if (!file.remote) {
|
|
35
33
|
// immediately update local files.
|
|
36
|
-
|
|
34
|
+
this.updateFileData(file);
|
|
37
35
|
}
|
|
38
36
|
// this will download any original remote file and trigger a re-upload to the
|
|
39
37
|
// new file's identity, in addition to storing it on disk
|
|
40
38
|
const processedFile = await (
|
|
41
39
|
await this.context.files
|
|
42
40
|
).add(file, { cloneRemote: true });
|
|
43
|
-
|
|
41
|
+
this.updateFileData(processedFile);
|
|
44
42
|
};
|
|
45
43
|
|
|
46
44
|
/**
|
|
@@ -49,22 +47,49 @@ export class FileManager extends Disposable {
|
|
|
49
47
|
*/
|
|
50
48
|
get = (
|
|
51
49
|
id: string,
|
|
52
|
-
options: {
|
|
50
|
+
options: {
|
|
51
|
+
downloadRemote?: boolean;
|
|
52
|
+
ctx: Context;
|
|
53
|
+
fileContext: EntityFileContext;
|
|
54
|
+
},
|
|
53
55
|
) => {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
+
const cacheKey = `${options.fileContext.oid}:${String(options.fileContext.key)}:${id}`;
|
|
57
|
+
const cachedFile = this.cache.get(cacheKey)?.deref();
|
|
58
|
+
if (cachedFile) {
|
|
59
|
+
return cachedFile;
|
|
56
60
|
}
|
|
61
|
+
this.cache.delete(cacheKey);
|
|
57
62
|
const file = new EntityFile(id, options);
|
|
58
|
-
this.cache.set(
|
|
59
|
-
this.
|
|
63
|
+
this.cache.set(cacheKey, this.context.weakRef(file));
|
|
64
|
+
const data = this.fileData.get(id)?.deref();
|
|
65
|
+
if (data) {
|
|
66
|
+
file[UPDATE](data);
|
|
67
|
+
} else {
|
|
68
|
+
this.fileData.delete(id);
|
|
69
|
+
this.load(file);
|
|
70
|
+
}
|
|
60
71
|
return file;
|
|
61
72
|
};
|
|
62
73
|
|
|
74
|
+
private updateFileData = (data: FileData) => {
|
|
75
|
+
this.fileData.set(data.id, this.context.weakRef(data));
|
|
76
|
+
for (const [key, fileRef] of this.cache) {
|
|
77
|
+
const file = fileRef.deref();
|
|
78
|
+
if (!file) {
|
|
79
|
+
this.cache.delete(key);
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
if (file.id === data.id) {
|
|
83
|
+
file[UPDATE](data);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
|
|
63
88
|
private load = async (file: EntityFile) => {
|
|
64
89
|
const fileData = await (await this.context.files).get(file.id);
|
|
65
90
|
// immediately apply any file data we have
|
|
66
91
|
if (fileData) {
|
|
67
|
-
|
|
92
|
+
this.updateFileData(fileData);
|
|
68
93
|
}
|
|
69
94
|
|
|
70
95
|
if (!fileData?.url && (!fileData || fileData.remote)) {
|
|
@@ -96,7 +121,7 @@ export class FileManager extends Disposable {
|
|
|
96
121
|
url: result.data.url,
|
|
97
122
|
};
|
|
98
123
|
await (await this.context.files).update(copyWithUrl);
|
|
99
|
-
|
|
124
|
+
this.updateFileData(result.data);
|
|
100
125
|
} else {
|
|
101
126
|
this.context.log('error', 'Failed to load file', result);
|
|
102
127
|
if (!fileData) {
|