Skip to content

Commit f37502e

Browse files
committed
Update examples and emulation
1 parent 3335603 commit f37502e

File tree

2 files changed

+77
-32
lines changed

2 files changed

+77
-32
lines changed

emulation/storage.js

Lines changed: 63 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,9 @@ class Record extends Emitter {
4141

4242
async #load() {
4343
if (this.#data !== null) return this;
44-
this.#data = await this.#storage.get(this.#id);
45-
if (this.#data) {
44+
const rawData = await this.#storage.get(this.#id);
45+
if (rawData) {
46+
this.#data = JSON.parse(JSON.stringify(rawData));
4647
this.#convertToReferences(this.#data);
4748
this.#defineProperties();
4849
}
@@ -123,11 +124,6 @@ class Record extends Emitter {
123124
this.#data = null;
124125
this.#changes = {};
125126
}
126-
127-
async ensureLoaded() {
128-
if (this.#data !== null) return this;
129-
return await this.#load();
130-
}
131127
}
132128

133129
class SyncManager {
@@ -160,15 +156,53 @@ class SyncManager {
160156
}
161157
}
162158

159+
class Collection {
160+
#storage;
161+
#name;
162+
163+
constructor(storage, name) {
164+
this.#storage = storage;
165+
this.#name = name;
166+
}
167+
168+
get name() {
169+
return this.#name;
170+
}
171+
172+
async insert(data) {
173+
const id = generateUUID();
174+
const record = { ...data, $type: this.#name };
175+
await this.#storage.saveData(id, record);
176+
return this.#storage.record(id);
177+
}
178+
179+
async get(id) {
180+
return this.#storage.get(id);
181+
}
182+
183+
async delete(id) {
184+
return this.#storage.delete(id);
185+
}
186+
187+
async update(id, delta) {
188+
return this.#storage.update(id, delta);
189+
}
190+
191+
async record(id) {
192+
return this.#storage.record(id);
193+
}
194+
}
195+
163196
class Storage {
164197
#data = new Map();
165198
#records = new Map();
166199
#sync = null;
167200
#cache = new Map();
168201
#updates = [];
202+
#schema = null;
169203

170-
// eslint-disable-next-line no-unused-vars
171204
constructor(options = {}) {
205+
if (options.schema) this.#schema = options.schema;
172206
this.#sync = new SyncManager();
173207
return this.#init();
174208
}
@@ -180,9 +214,22 @@ class Storage {
180214
this.#data.set(id, item);
181215
this.#cache.set(id, item);
182216
}
217+
this.#initCollections();
183218
return this;
184219
}
185220

221+
#initCollections() {
222+
const entities = this.#schema?.entities;
223+
if (!entities) return;
224+
for (const [name] of entities.entries?.() ?? Object.entries(entities)) {
225+
this[name] = new Collection(this, name);
226+
}
227+
}
228+
229+
get schema() {
230+
return this.#schema;
231+
}
232+
186233
#emitUpdate(id, data, delta) {
187234
const emitter = this.#records.get(id);
188235
if (emitter) {
@@ -207,7 +254,7 @@ class Storage {
207254
return this.#data.has(id);
208255
}
209256

210-
async get(id) {
257+
async loadData(id) {
211258
if (this.#cache.has(id)) {
212259
return this.#cache.get(id);
213260
}
@@ -220,6 +267,10 @@ class Storage {
220267
return null;
221268
}
222269

270+
async get(id) {
271+
return this.loadData(id);
272+
}
273+
223274
getCachedData(id) {
224275
return this.#cache.has(id) ? this.#cache.get(id) : null;
225276
}
@@ -281,14 +332,10 @@ class Storage {
281332

282333
async record(id) {
283334
if (!this.#records.has(id)) {
284-
const recordPromise = new Record(id, this);
285-
const record = await recordPromise;
335+
const record = await new Record(id, this);
286336
this.#records.set(id, record);
287-
return record;
288337
}
289-
const record = this.#records.get(id);
290-
await record.ensureLoaded();
291-
return record;
338+
return this.#records.get(id);
292339
}
293340

294341
// eslint-disable-next-line no-unused-vars
@@ -307,4 +354,4 @@ class Storage {
307354

308355
const open = async (options = {}) => new Storage(options);
309356

310-
module.exports = { Storage, open, SyncManager };
357+
module.exports = { Storage, Collection, Record, open, SyncManager };

example.js

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
'use strict';
22

33
const globalStorage = require('./gs.js');
4+
const xxii = require('xxii-schema');
45

56
const main = async () => {
6-
const storage = await globalStorage.open();
7+
const xxiiSchema = await xxii.load();
8+
console.log(xxiiSchema);
9+
const storage = await globalStorage.open({ schema: xxiiSchema });
710

811
await storage.sync
912
.addNode({
@@ -36,20 +39,19 @@ const main = async () => {
3639
const nodes = storage.sync.listNodes();
3740
console.log('List nodes', nodes);
3841

39-
// Domain logic
42+
// Implicit API - Record with dynamic getters/setters
4043

4144
const authorData = { name: 'Timur', email: 'timur@example.com' };
4245
const authorId = await storage.insert(authorData);
46+
const authorRecord = await storage.record(authorId);
47+
authorRecord.email = 'timur.shemsedinov@gmail.com';
48+
await authorRecord.save();
4349

4450
const post = { title: 'Example', content: 'Text', author: authorId };
45-
const id = await storage.insert(post);
46-
47-
// Implicit API - Record with dynamic getters/setters
48-
49-
const postRecord = await storage.record(id);
51+
const postRecord = await storage.Post.insert(post);
5052

5153
postRecord.on('update', (data, delta) => {
52-
console.log('Record updated:', { id, data, delta });
54+
console.log('Record updated:', { id: postRecord.id, data, delta });
5355
});
5456

5557
console.log('Title:', postRecord.title);
@@ -64,19 +66,15 @@ const main = async () => {
6466

6567
await postRecord.save();
6668

67-
const authorRecord = await postRecord.author.record();
68-
console.log('Author name:', authorRecord.name);
69-
70-
// Delete record
71-
// await postRecord.delete();
69+
console.log('Author name:', postRecord.author.name);
7270

7371
// Explicit API (still available)
7472

75-
const exists = await storage.has(id);
73+
const exists = await storage.has(postRecord.id);
7674
if (exists) {
77-
const data = await storage.get(id);
75+
const data = await storage.get(postRecord.id);
7876
data.content += ' more changes';
79-
await storage.set(id, data);
77+
await storage.set(postRecord.id, data);
8078
}
8179

8280
await storage.sync.start();

0 commit comments

Comments
 (0)