@zucker-framework/things 1.0.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/index.js ADDED
@@ -0,0 +1,451 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+
21
+ // src/index.ts
22
+ var index_exports = {};
23
+ __export(index_exports, {
24
+ DefaultThingsDataService: () => DefaultThingsDataService,
25
+ EventLevel: () => EventLevel,
26
+ InMemoryThingManager: () => InMemoryThingManager,
27
+ PropertyAccessMode: () => PropertyAccessMode,
28
+ ThingState: () => ThingState,
29
+ ThingsModule: () => ThingsModule,
30
+ convertValue: () => convertValue,
31
+ createEventMessage: () => createEventMessage,
32
+ createMessageId: () => createMessageId,
33
+ createMetadata: () => createMetadata,
34
+ createReportPropertyMessage: () => createReportPropertyMessage,
35
+ mergeMetadata: () => mergeMetadata
36
+ });
37
+ module.exports = __toCommonJS(index_exports);
38
+
39
+ // src/data-type.ts
40
+ function convertValue(type, raw) {
41
+ if (raw === null || raw === void 0) return raw;
42
+ switch (type.id) {
43
+ case "int":
44
+ case "long": {
45
+ const n = Number(raw);
46
+ return isNaN(n) ? raw : Math.trunc(n);
47
+ }
48
+ case "float":
49
+ case "double": {
50
+ const n = Number(raw);
51
+ if (isNaN(n)) return raw;
52
+ if (type.scale !== void 0) {
53
+ return parseFloat(n.toFixed(type.scale));
54
+ }
55
+ return n;
56
+ }
57
+ case "boolean": {
58
+ if (typeof raw === "boolean") return raw;
59
+ const tv = type.trueValue ?? "true";
60
+ const fv = type.falseValue ?? "false";
61
+ if (String(raw) === tv) return true;
62
+ if (String(raw) === fv) return false;
63
+ return Boolean(raw);
64
+ }
65
+ case "string":
66
+ case "password":
67
+ return String(raw);
68
+ case "date": {
69
+ if (raw instanceof Date) return raw.getTime();
70
+ const n = Number(raw);
71
+ return isNaN(n) ? new Date(String(raw)).getTime() : n;
72
+ }
73
+ case "enum": {
74
+ const match = type.elements.find((e) => e.value === raw || String(e.value) === String(raw));
75
+ return match ? match.value : raw;
76
+ }
77
+ default:
78
+ return raw;
79
+ }
80
+ }
81
+ __name(convertValue, "convertValue");
82
+
83
+ // src/metadata.ts
84
+ var PropertyAccessMode = /* @__PURE__ */ (function(PropertyAccessMode2) {
85
+ PropertyAccessMode2["READ"] = "r";
86
+ PropertyAccessMode2["WRITE"] = "w";
87
+ PropertyAccessMode2["READ_WRITE"] = "rw";
88
+ return PropertyAccessMode2;
89
+ })({});
90
+ var EventLevel = /* @__PURE__ */ (function(EventLevel2) {
91
+ EventLevel2["OTHER"] = "other";
92
+ EventLevel2["WARN"] = "warn";
93
+ EventLevel2["ERROR"] = "error";
94
+ return EventLevel2;
95
+ })({});
96
+ function mergeMetadata(base, patch) {
97
+ const mergeList = /* @__PURE__ */ __name((a, b = []) => {
98
+ const map = new Map(a.map((i) => [
99
+ i.id,
100
+ i
101
+ ]));
102
+ for (const item of b) {
103
+ map.set(item.id, item);
104
+ }
105
+ return Array.from(map.values());
106
+ }, "mergeList");
107
+ return {
108
+ properties: mergeList(base.properties, patch.properties),
109
+ functions: mergeList(base.functions, patch.functions),
110
+ events: mergeList(base.events, patch.events),
111
+ tags: mergeList(base.tags ?? [], patch.tags)
112
+ };
113
+ }
114
+ __name(mergeMetadata, "mergeMetadata");
115
+ function createMetadata(partial = {}) {
116
+ return {
117
+ properties: partial.properties ?? [],
118
+ functions: partial.functions ?? [],
119
+ events: partial.events ?? [],
120
+ tags: partial.tags ?? []
121
+ };
122
+ }
123
+ __name(createMetadata, "createMetadata");
124
+
125
+ // src/thing.ts
126
+ var ThingState = /* @__PURE__ */ (function(ThingState2) {
127
+ ThingState2["INACTIVE"] = "notActive";
128
+ ThingState2["OFFLINE"] = "offline";
129
+ ThingState2["ONLINE"] = "online";
130
+ return ThingState2;
131
+ })({});
132
+
133
+ // src/thing-manager.ts
134
+ var import_common = require("@nestjs/common");
135
+ function _ts_decorate(decorators, target, key, desc) {
136
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
137
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
138
+ r = Reflect.decorate(decorators, target, key, desc);
139
+ } else {
140
+ for (var i = decorators.length - 1; i >= 0; i--) {
141
+ if (d = decorators[i]) {
142
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
143
+ }
144
+ }
145
+ }
146
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
147
+ }
148
+ __name(_ts_decorate, "_ts_decorate");
149
+ var InMemoryThingManager = class {
150
+ static {
151
+ __name(this, "InMemoryThingManager");
152
+ }
153
+ types = /* @__PURE__ */ new Map();
154
+ things = /* @__PURE__ */ new Map();
155
+ async getThingType(typeId) {
156
+ return this.types.get(typeId);
157
+ }
158
+ async registerThingType(type) {
159
+ this.types.set(type.id, type);
160
+ }
161
+ async getThing(thingId) {
162
+ return this.things.get(thingId);
163
+ }
164
+ async registerThing(thing) {
165
+ const existing = this.things.get(thing.id);
166
+ this.things.set(thing.id, {
167
+ ...existing,
168
+ ...thing,
169
+ state: existing?.state ?? ThingState.INACTIVE
170
+ });
171
+ }
172
+ async unregisterThing(thingId) {
173
+ this.things.delete(thingId);
174
+ }
175
+ async updateState(thingId, state, timestamp) {
176
+ const thing = this.things.get(thingId);
177
+ if (!thing) return;
178
+ const update = {
179
+ state
180
+ };
181
+ if (state === ThingState.ONLINE) {
182
+ update.onlineTime = timestamp ?? Date.now();
183
+ } else if (state === ThingState.OFFLINE) {
184
+ update.offlineTime = timestamp ?? Date.now();
185
+ }
186
+ this.things.set(thingId, {
187
+ ...thing,
188
+ ...update
189
+ });
190
+ }
191
+ async getEffectiveMetadata(thingId) {
192
+ const thing = this.things.get(thingId);
193
+ if (!thing) return void 0;
194
+ const type = this.types.get(thing.thingTypeId);
195
+ if (!type) return void 0;
196
+ if (!thing.metadataPatch) {
197
+ return type.metadata;
198
+ }
199
+ return mergeMetadata(type.metadata, thing.metadataPatch);
200
+ }
201
+ /** 获取指定类型的所有实例 */
202
+ getThingsByType(typeId) {
203
+ return Array.from(this.things.values()).filter((t) => t.thingTypeId === typeId);
204
+ }
205
+ /** 获取所有在线实例数量 */
206
+ countOnline() {
207
+ return Array.from(this.things.values()).filter((t) => t.state === ThingState.ONLINE).length;
208
+ }
209
+ };
210
+ InMemoryThingManager = _ts_decorate([
211
+ (0, import_common.Injectable)()
212
+ ], InMemoryThingManager);
213
+
214
+ // src/message.ts
215
+ function createMessageId() {
216
+ return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
217
+ }
218
+ __name(createMessageId, "createMessageId");
219
+ function createReportPropertyMessage(thingId, thingType, properties, extra) {
220
+ return {
221
+ messageType: "ReportProperty",
222
+ messageId: createMessageId(),
223
+ thingId,
224
+ thingType,
225
+ timestamp: Date.now(),
226
+ properties,
227
+ ...extra
228
+ };
229
+ }
230
+ __name(createReportPropertyMessage, "createReportPropertyMessage");
231
+ function createEventMessage(thingId, thingType, event, data) {
232
+ return {
233
+ messageType: "Event",
234
+ messageId: createMessageId(),
235
+ thingId,
236
+ thingType,
237
+ timestamp: Date.now(),
238
+ event,
239
+ data
240
+ };
241
+ }
242
+ __name(createEventMessage, "createEventMessage");
243
+
244
+ // src/property-log.ts
245
+ var import_common2 = require("@nestjs/common");
246
+ function _ts_decorate2(decorators, target, key, desc) {
247
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
248
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
249
+ r = Reflect.decorate(decorators, target, key, desc);
250
+ } else {
251
+ for (var i = decorators.length - 1; i >= 0; i--) {
252
+ if (d = decorators[i]) {
253
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
254
+ }
255
+ }
256
+ }
257
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
258
+ }
259
+ __name(_ts_decorate2, "_ts_decorate");
260
+ function _ts_metadata(metadataKey, metadataValue) {
261
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
262
+ return Reflect.metadata(metadataKey, metadataValue);
263
+ }
264
+ }
265
+ __name(_ts_metadata, "_ts_metadata");
266
+ var DefaultThingsDataService = class {
267
+ static {
268
+ __name(this, "DefaultThingsDataService");
269
+ }
270
+ tsService;
271
+ constructor(tsService) {
272
+ this.tsService = tsService;
273
+ }
274
+ propertyMetric(thingType) {
275
+ return `thing_property_${thingType}`;
276
+ }
277
+ eventMetric(thingType, eventId) {
278
+ return `thing_event_${thingType}_${eventId}`;
279
+ }
280
+ async saveProperties(message) {
281
+ const metric = this.propertyMetric(message.thingType);
282
+ const points = Object.entries(message.properties).map(([key, value]) => ({
283
+ timestamp: message.propertySourceTimes?.[key] ?? message.timestamp,
284
+ tags: {
285
+ thingId: message.thingId,
286
+ thingType: message.thingType,
287
+ property: key
288
+ },
289
+ values: {
290
+ value: typeof value === "object" ? JSON.stringify(value) : value,
291
+ state: message.propertyStates?.[key] ?? "success"
292
+ }
293
+ }));
294
+ for (const point of points) {
295
+ const propMetric = `thing_property_${message.thingType}_${point.tags["property"]}`;
296
+ await this.tsService.save({
297
+ ...point,
298
+ tags: {
299
+ thingId: point.tags["thingId"],
300
+ thingType: point.tags["thingType"]
301
+ }
302
+ });
303
+ void propMetric;
304
+ }
305
+ if (points.length > 0) {
306
+ await this.tsService.saveBatch(points.map((p) => ({
307
+ ...p,
308
+ tags: {
309
+ ...p.tags
310
+ },
311
+ values: {
312
+ ...p.values,
313
+ metric
314
+ }
315
+ })));
316
+ }
317
+ }
318
+ async saveEvent(message) {
319
+ const metric = this.eventMetric(message.thingType, message.event);
320
+ const data = {
321
+ timestamp: message.timestamp,
322
+ tags: {
323
+ thingId: message.thingId,
324
+ thingType: message.thingType,
325
+ event: message.event
326
+ },
327
+ values: {
328
+ data: typeof message.data === "object" ? JSON.stringify(message.data) : message.data,
329
+ metric
330
+ }
331
+ };
332
+ await this.tsService.save(data);
333
+ }
334
+ async queryPropertyLogs(query) {
335
+ const tsQuery = {
336
+ metric: this.propertyMetric(query.thingType),
337
+ from: query.from,
338
+ to: query.to,
339
+ tags: {
340
+ thingId: query.thingId,
341
+ property: query.id
342
+ },
343
+ limit: query.limit,
344
+ order: query.order
345
+ };
346
+ const results = await this.tsService.query(tsQuery);
347
+ return results.map((r) => ({
348
+ property: String(r.tags["property"] ?? query.id),
349
+ value: r.values["value"],
350
+ thingId: String(r.tags["thingId"]),
351
+ thingType: String(r.tags["thingType"] ?? query.thingType),
352
+ timestamp: r.timestamp,
353
+ state: r.values["state"]
354
+ }));
355
+ }
356
+ async queryEventLogs(query) {
357
+ const tsQuery = {
358
+ metric: this.eventMetric(query.thingType, query.id),
359
+ from: query.from,
360
+ to: query.to,
361
+ tags: {
362
+ thingId: query.thingId
363
+ },
364
+ limit: query.limit,
365
+ order: query.order
366
+ };
367
+ const results = await this.tsService.query(tsQuery);
368
+ return results.map((r) => {
369
+ let data = r.values["data"];
370
+ if (typeof data === "string") {
371
+ try {
372
+ data = JSON.parse(data);
373
+ } catch {
374
+ }
375
+ }
376
+ return {
377
+ event: String(r.tags["event"] ?? query.id),
378
+ data,
379
+ thingId: String(r.tags["thingId"]),
380
+ thingType: String(r.tags["thingType"] ?? query.thingType),
381
+ timestamp: r.timestamp
382
+ };
383
+ });
384
+ }
385
+ async aggregateProperties(thingId, thingType, property, aggQuery) {
386
+ const query = {
387
+ ...aggQuery,
388
+ metric: this.propertyMetric(thingType),
389
+ tags: {
390
+ ...aggQuery.tags,
391
+ thingId,
392
+ property
393
+ }
394
+ };
395
+ return this.tsService.aggregate(query);
396
+ }
397
+ };
398
+ DefaultThingsDataService = _ts_decorate2([
399
+ (0, import_common2.Injectable)(),
400
+ _ts_metadata("design:type", Function),
401
+ _ts_metadata("design:paramtypes", [
402
+ typeof TimeSeriesService === "undefined" ? Object : TimeSeriesService
403
+ ])
404
+ ], DefaultThingsDataService);
405
+
406
+ // src/things.module.ts
407
+ var import_common3 = require("@nestjs/common");
408
+ function _ts_decorate3(decorators, target, key, desc) {
409
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
410
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
411
+ r = Reflect.decorate(decorators, target, key, desc);
412
+ } else {
413
+ for (var i = decorators.length - 1; i >= 0; i--) {
414
+ if (d = decorators[i]) {
415
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
416
+ }
417
+ }
418
+ }
419
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
420
+ }
421
+ __name(_ts_decorate3, "_ts_decorate");
422
+ var ThingsModule = class {
423
+ static {
424
+ __name(this, "ThingsModule");
425
+ }
426
+ };
427
+ ThingsModule = _ts_decorate3([
428
+ (0, import_common3.Module)({
429
+ providers: [
430
+ InMemoryThingManager
431
+ ],
432
+ exports: [
433
+ InMemoryThingManager
434
+ ]
435
+ })
436
+ ], ThingsModule);
437
+ // Annotate the CommonJS export names for ESM import in node:
438
+ 0 && (module.exports = {
439
+ DefaultThingsDataService,
440
+ EventLevel,
441
+ InMemoryThingManager,
442
+ PropertyAccessMode,
443
+ ThingState,
444
+ ThingsModule,
445
+ convertValue,
446
+ createEventMessage,
447
+ createMessageId,
448
+ createMetadata,
449
+ createReportPropertyMessage,
450
+ mergeMetadata
451
+ });