raffel 1.0.2 → 1.0.3

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.
@@ -0,0 +1,170 @@
1
+ /**
2
+ * JSON Server — In-Memory Store
3
+ *
4
+ * Shared data store with change notifications and optional file persistence.
5
+ */
6
+ import { readFileSync, writeFileSync } from 'node:fs';
7
+ export class InMemoryStore {
8
+ rows = new Map();
9
+ listeners = new Set();
10
+ idKey;
11
+ filePath;
12
+ nextNumericId = new Map();
13
+ flushTimer = null;
14
+ constructor(db, options = {}) {
15
+ this.idKey = options.idKey ?? 'id';
16
+ this.filePath = options.filePath;
17
+ for (const [resource, items] of Object.entries(db)) {
18
+ const map = new Map();
19
+ let maxId = 0;
20
+ for (const item of items) {
21
+ const id = item[this.idKey];
22
+ if (id !== undefined) {
23
+ map.set(id, { ...item });
24
+ if (typeof id === 'number' && id > maxId)
25
+ maxId = id;
26
+ }
27
+ }
28
+ this.rows.set(resource, map);
29
+ this.nextNumericId.set(resource, maxId + 1);
30
+ }
31
+ }
32
+ resources() {
33
+ return [...this.rows.keys()];
34
+ }
35
+ list(resource, query = {}) {
36
+ const map = this.rows.get(resource);
37
+ if (!map)
38
+ return { data: [], total: 0 };
39
+ let result = [...map.values()];
40
+ // Field filters — skip _ prefixed params
41
+ for (const [key, value] of Object.entries(query)) {
42
+ if (key.startsWith('_') || value === undefined || value === null)
43
+ continue;
44
+ result = result.filter(item => String(item[key]) === String(value));
45
+ }
46
+ // Full-text search
47
+ if (query._q) {
48
+ const q = String(query._q).toLowerCase();
49
+ result = result.filter(item => Object.values(item).some(v => String(v).toLowerCase().includes(q)));
50
+ }
51
+ // Sort
52
+ if (query._sort) {
53
+ const key = query._sort;
54
+ const order = query._order === 'desc' ? -1 : 1;
55
+ result.sort((a, b) => {
56
+ const av = a[key];
57
+ const bv = b[key];
58
+ return (av < bv ? -1 : av > bv ? 1 : 0) * order;
59
+ });
60
+ }
61
+ const total = result.length;
62
+ // Paginate
63
+ if (query._limit !== undefined) {
64
+ const limit = Math.max(1, Number(query._limit));
65
+ const page = Math.max(1, Number(query._page ?? 1));
66
+ result = result.slice((page - 1) * limit, page * limit);
67
+ }
68
+ return { data: result, total };
69
+ }
70
+ get(resource, id) {
71
+ return this.rows.get(resource)?.get(id) ?? null;
72
+ }
73
+ create(resource, data) {
74
+ let map = this.rows.get(resource);
75
+ if (!map) {
76
+ map = new Map();
77
+ this.rows.set(resource, map);
78
+ this.nextNumericId.set(resource, 1);
79
+ }
80
+ const providedId = data[this.idKey];
81
+ const id = providedId !== undefined
82
+ ? providedId
83
+ : this.nextNumericId.get(resource) ?? 1;
84
+ if (typeof id === 'number') {
85
+ const next = this.nextNumericId.get(resource) ?? 1;
86
+ if (id >= next)
87
+ this.nextNumericId.set(resource, id + 1);
88
+ }
89
+ const record = { ...data, [this.idKey]: id };
90
+ map.set(id, record);
91
+ this.scheduleFlush();
92
+ this.emit({ op: 'create', resource, id, data: record });
93
+ return record;
94
+ }
95
+ replace(resource, id, data) {
96
+ const map = this.rows.get(resource);
97
+ const prev = map?.get(id);
98
+ if (!map || !prev)
99
+ return null;
100
+ const record = { ...data, [this.idKey]: id };
101
+ map.set(id, record);
102
+ this.scheduleFlush();
103
+ this.emit({ op: 'replace', resource, id, data: record, prev });
104
+ return record;
105
+ }
106
+ update(resource, id, patch) {
107
+ const map = this.rows.get(resource);
108
+ const prev = map?.get(id);
109
+ if (!map || !prev)
110
+ return null;
111
+ const record = { ...prev, ...patch, [this.idKey]: id };
112
+ map.set(id, record);
113
+ this.scheduleFlush();
114
+ this.emit({ op: 'update', resource, id, data: record, prev });
115
+ return record;
116
+ }
117
+ delete(resource, id) {
118
+ const map = this.rows.get(resource);
119
+ const prev = map?.get(id);
120
+ if (!map || !prev)
121
+ return null;
122
+ map.delete(id);
123
+ this.scheduleFlush();
124
+ this.emit({ op: 'delete', resource, id, prev });
125
+ return prev;
126
+ }
127
+ subscribe(callback) {
128
+ this.listeners.add(callback);
129
+ return () => this.listeners.delete(callback);
130
+ }
131
+ toJSON() {
132
+ const db = {};
133
+ for (const [resource, map] of this.rows.entries()) {
134
+ db[resource] = [...map.values()];
135
+ }
136
+ return db;
137
+ }
138
+ emit(event) {
139
+ for (const listener of this.listeners)
140
+ listener(event);
141
+ }
142
+ scheduleFlush() {
143
+ if (!this.filePath)
144
+ return;
145
+ if (this.flushTimer)
146
+ clearTimeout(this.flushTimer);
147
+ this.flushTimer = setTimeout(() => {
148
+ writeFileSync(this.filePath, JSON.stringify(this.toJSON(), null, 2));
149
+ this.flushTimer = null;
150
+ }, 100);
151
+ }
152
+ }
153
+ /** Load a JSON database from file, returning an empty object on error. */
154
+ export function loadDb(filePath) {
155
+ try {
156
+ return JSON.parse(readFileSync(filePath, 'utf8'));
157
+ }
158
+ catch {
159
+ return {};
160
+ }
161
+ }
162
+ /**
163
+ * Coerce a URL path segment string to the correct id type.
164
+ * Integer strings like "1" become the number 1; everything else stays a string.
165
+ */
166
+ export function normalizeId(id) {
167
+ const n = Number(id);
168
+ return Number.isInteger(n) && String(n) === id ? n : id;
169
+ }
170
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/json-server/store.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "raffel",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "Unified multi-protocol server runtime. One core, multiple transports.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",