@shaxpir/duiduidui-models 1.25.11 → 1.26.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/models/Chat.js +0 -11
- package/dist/models/Model.d.ts +8 -0
- package/dist/models/Model.js +24 -1
- package/dist/models/SharedContent.js +0 -6
- package/dist/repo/ShareSync.js +2 -15
- package/package.json +1 -1
package/dist/models/Chat.js
CHANGED
|
@@ -54,36 +54,25 @@ class Chat extends SharedContent_1.SharedContent {
|
|
|
54
54
|
*/
|
|
55
55
|
async modelUpdated() {
|
|
56
56
|
this.checkDisposed('Chat.modelUpdated');
|
|
57
|
-
const chatId = this.id;
|
|
58
|
-
const title = this.title;
|
|
59
|
-
console.log(`[Chat.modelUpdated] START chat=${chatId} title=${JSON.stringify(title)} acquireCount=${this.acquireCount}`);
|
|
60
57
|
// Update manifests for all participants
|
|
61
58
|
await super.modelUpdated();
|
|
62
|
-
console.log(`[Chat.modelUpdated] after super.modelUpdated chat=${chatId} acquireCount=${this.acquireCount}`);
|
|
63
59
|
// Update workspace stubs for all participants
|
|
64
60
|
const stub = this.toStub();
|
|
65
61
|
const userIds = this.getAllSharedUserIds();
|
|
66
|
-
console.log(`[Chat.modelUpdated] stub.title=${JSON.stringify(stub.title)} userIds=${JSON.stringify(userIds)}`);
|
|
67
62
|
for (const userId of userIds) {
|
|
68
63
|
try {
|
|
69
64
|
const workspaceId = shaxpir_common_1.CachingHasher.makeMd5Base62Hash(userId + "-" + ContentKind_1.ContentKind.WORKSPACE);
|
|
70
65
|
const workspace = await this.shareSync.acquire(ContentKind_1.ContentKind.WORKSPACE, workspaceId);
|
|
71
66
|
if (workspace && workspace.exists()) {
|
|
72
|
-
console.log(`[Chat.modelUpdated] upserting stub for user=${userId} workspace=${workspaceId}`);
|
|
73
67
|
// Cast needed to avoid circular dependency between Chat and Workspace
|
|
74
68
|
workspace.upsertChatStub(stub);
|
|
75
69
|
workspace.release();
|
|
76
70
|
}
|
|
77
|
-
else {
|
|
78
|
-
console.log(`[Chat.modelUpdated] workspace not found for user=${userId} workspace=${workspaceId}`);
|
|
79
|
-
}
|
|
80
71
|
}
|
|
81
72
|
catch (err) {
|
|
82
|
-
console.error(`[Chat.modelUpdated] ERROR for user=${userId}:`, err);
|
|
83
73
|
this.shareSync.onError(err, 'Chat.modelUpdated.workspaceStub');
|
|
84
74
|
}
|
|
85
75
|
}
|
|
86
|
-
console.log(`[Chat.modelUpdated] END chat=${chatId}`);
|
|
87
76
|
}
|
|
88
77
|
// ---- Getters ----
|
|
89
78
|
get payload() {
|
package/dist/models/Model.d.ts
CHANGED
|
@@ -18,6 +18,14 @@ export declare abstract class Model {
|
|
|
18
18
|
protected shareSync: ShareSync;
|
|
19
19
|
private _subscribingPromise;
|
|
20
20
|
private _acquireCount;
|
|
21
|
+
private _disposeTimer;
|
|
22
|
+
/**
|
|
23
|
+
* How long to wait (ms) after refcount hits 0 before actually disposing.
|
|
24
|
+
* This allows rapid acquire/release cycles (e.g., multiple concurrent
|
|
25
|
+
* modelUpdated calls) to reuse the model without it being destroyed
|
|
26
|
+
* and re-fetched in between.
|
|
27
|
+
*/
|
|
28
|
+
private static readonly DISPOSE_DELAY_MS;
|
|
21
29
|
constructor(doc: Doc, shouldAcquire: boolean, shareSync: ShareSync);
|
|
22
30
|
get kind(): ContentKind;
|
|
23
31
|
get ref(): ContentRef;
|
package/dist/models/Model.js
CHANGED
|
@@ -13,6 +13,7 @@ class Model {
|
|
|
13
13
|
this._clearEventListeners = null;
|
|
14
14
|
this._subscribingPromise = null;
|
|
15
15
|
this._acquireCount = 0;
|
|
16
|
+
this._disposeTimer = null;
|
|
16
17
|
const model = this;
|
|
17
18
|
model.doc = doc;
|
|
18
19
|
model.shareSync = shareSync;
|
|
@@ -95,6 +96,11 @@ class Model {
|
|
|
95
96
|
return this._acquireCount;
|
|
96
97
|
}
|
|
97
98
|
async acquire(minVersion) {
|
|
99
|
+
// Cancel any pending deferred disposal — this model is being reused
|
|
100
|
+
if (this._disposeTimer) {
|
|
101
|
+
clearTimeout(this._disposeTimer);
|
|
102
|
+
this._disposeTimer = null;
|
|
103
|
+
}
|
|
98
104
|
this._acquireCount++;
|
|
99
105
|
if (!this._hasEventListeners) {
|
|
100
106
|
this._setupEventListeners();
|
|
@@ -113,7 +119,17 @@ class Model {
|
|
|
113
119
|
this.log(`RELEASE: (${this.compoundKey}); acquireCount = ${this.acquireCount}`);
|
|
114
120
|
if (this._acquireCount <= 0) {
|
|
115
121
|
this._acquireCount = 0;
|
|
116
|
-
|
|
122
|
+
// Defer disposal to allow rapid re-acquire without destroying the doc.
|
|
123
|
+
// If acquire() is called before the timer fires, it cancels the timer.
|
|
124
|
+
if (!this._disposeTimer) {
|
|
125
|
+
this._disposeTimer = setTimeout(() => {
|
|
126
|
+
this._disposeTimer = null;
|
|
127
|
+
// Only dispose if still unreferenced
|
|
128
|
+
if (this._acquireCount <= 0) {
|
|
129
|
+
this.dispose();
|
|
130
|
+
}
|
|
131
|
+
}, Model.DISPOSE_DELAY_MS);
|
|
132
|
+
}
|
|
117
133
|
}
|
|
118
134
|
}
|
|
119
135
|
dispose() {
|
|
@@ -301,3 +317,10 @@ class Model {
|
|
|
301
317
|
}
|
|
302
318
|
exports.Model = Model;
|
|
303
319
|
Model.CHANGED = "MODEL_CHANGED";
|
|
320
|
+
/**
|
|
321
|
+
* How long to wait (ms) after refcount hits 0 before actually disposing.
|
|
322
|
+
* This allows rapid acquire/release cycles (e.g., multiple concurrent
|
|
323
|
+
* modelUpdated calls) to reuse the model without it being destroyed
|
|
324
|
+
* and re-fetched in between.
|
|
325
|
+
*/
|
|
326
|
+
Model.DISPOSE_DELAY_MS = 5000;
|
|
@@ -28,27 +28,21 @@ class SharedContent extends Content_1.Content {
|
|
|
28
28
|
async modelUpdated() {
|
|
29
29
|
this.checkDisposed("SharedContent.modelUpdated");
|
|
30
30
|
this.acquire();
|
|
31
|
-
const contentId = this.id;
|
|
32
31
|
const userIds = this.getAllSharedUserIds();
|
|
33
32
|
for (const userId of userIds) {
|
|
34
33
|
try {
|
|
35
34
|
const manifestId = Manifest_1.Manifest.makeManifestId(userId);
|
|
36
|
-
console.log(`[SharedContent.modelUpdated] acquiring manifest ${manifestId} for content=${contentId}`);
|
|
37
35
|
const manifest = await this.shareSync.acquire(ContentKind_1.ContentKind.MANIFEST, manifestId);
|
|
38
|
-
console.log(`[SharedContent.modelUpdated] acquired manifest ${manifestId} exists=${manifest?.exists()}`);
|
|
39
36
|
if (manifest && manifest.exists()) {
|
|
40
37
|
manifest.update(this);
|
|
41
38
|
manifest.release();
|
|
42
|
-
console.log(`[SharedContent.modelUpdated] updated and released manifest ${manifestId}`);
|
|
43
39
|
}
|
|
44
40
|
}
|
|
45
41
|
catch (err) {
|
|
46
|
-
console.error(`[SharedContent.modelUpdated] ERROR acquiring manifest for user=${userId}:`, err);
|
|
47
42
|
this.shareSync.onError(err, 'SharedContent.modelUpdated.manifest');
|
|
48
43
|
}
|
|
49
44
|
}
|
|
50
45
|
this.release();
|
|
51
|
-
console.log(`[SharedContent.modelUpdated] released content=${contentId} acquireCount=${this.acquireCount}`);
|
|
52
46
|
}
|
|
53
47
|
}
|
|
54
48
|
exports.SharedContent = SharedContent;
|
package/dist/repo/ShareSync.js
CHANGED
|
@@ -389,28 +389,15 @@ class ShareSync {
|
|
|
389
389
|
// First, try getting the content from the cache
|
|
390
390
|
const compoundKey = `${kind}/${id}`;
|
|
391
391
|
if (this._modelCache.has(compoundKey)) {
|
|
392
|
-
|
|
393
|
-
console.log(`[ShareSync.load] cache hit: ${compoundKey} isDisposed=${cached._isDisposed} acquireCount=${cached.acquireCount}`);
|
|
394
|
-
return cached;
|
|
392
|
+
return this._modelCache.get(compoundKey);
|
|
395
393
|
}
|
|
396
394
|
// If not in the cache, get the model doc from the connection.
|
|
397
395
|
// Then wrap it and put it in the cache for future reference.
|
|
398
396
|
const doc = this._connection.get(kind, id);
|
|
399
397
|
if (!doc) {
|
|
400
|
-
console.error(`[ShareSync
|
|
398
|
+
console.error(`[ShareSync] connection.get(${kind}, ${id}) returned null/undefined doc`);
|
|
401
399
|
return null;
|
|
402
400
|
}
|
|
403
|
-
const docAny = doc;
|
|
404
|
-
const docState = {
|
|
405
|
-
hasData: typeof doc.data !== 'undefined',
|
|
406
|
-
version: doc.version,
|
|
407
|
-
type: doc.type ? 'set' : 'null',
|
|
408
|
-
wantsDestroy: docAny._wantsDestroy,
|
|
409
|
-
inflightFetch: docAny.inflightFetch?.length,
|
|
410
|
-
pendingFetch: docAny.pendingFetch?.length,
|
|
411
|
-
hasPending: docAny.hasPending?.(),
|
|
412
|
-
};
|
|
413
|
-
console.log(`[ShareSync.load] cache miss: ${compoundKey} doc=${JSON.stringify(docState)}`);
|
|
414
401
|
const model = this.wrap(kind, doc, false);
|
|
415
402
|
this._modelCache.set(compoundKey, model);
|
|
416
403
|
return model;
|