vaporous 0.0.4 → 0.0.5

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.
Files changed (3) hide show
  1. package/Vaporous.js +124 -37
  2. package/package.json +1 -1
  3. package/styles.css +1 -1
package/Vaporous.js CHANGED
@@ -14,7 +14,6 @@ const styles = fs.readFileSync(__dirname + '/styles.css')
14
14
  const Papa = require('papaparse')
15
15
 
16
16
  // These globals allow us to write functions from the HTML page directly without needing to stringify
17
- class google { }
18
17
  const document = {}
19
18
 
20
19
  const keyFromEvent = (event, bys) => bys.map(i => event[i.bySplit]).join('|')
@@ -35,7 +34,7 @@ const _sort = (order, data, ...keys) => {
35
34
 
36
35
  class Vaporous {
37
36
 
38
- constructor() {
37
+ constructor({ loggers } = {}) {
39
38
  this.events = [];
40
39
  this.visualisations = [];
41
40
  this.visualisationData = []
@@ -44,9 +43,50 @@ class Vaporous {
44
43
 
45
44
  this.savedMethods = {}
46
45
  this.checkpoints = {}
46
+
47
+ this.loggers = loggers
48
+ this.perf = null
49
+ this.totalTime = 0
50
+ }
51
+
52
+ manageEntry() {
53
+ if (this.loggers?.perf) {
54
+ const [, , method, ...origination] = new Error().stack.split('\n')
55
+ const invokedMethod = method.match(/Vaporous.(.+?) /)
56
+
57
+ let orig = origination.find(orig => {
58
+ const originator = orig.split("/").at(-1)
59
+ return !originator.includes("Vaporous")
60
+ })
61
+
62
+ orig = orig.split("/").at(-1)
63
+ const logLine = "(" + orig + " BEGIN " + invokedMethod[1]
64
+ this.loggers.perf('info', logLine)
65
+ this.perf = { time: new Date().valueOf(), logLine }
66
+ }
67
+ }
68
+
69
+ manageExit() {
70
+ if (this.loggers?.perf) {
71
+ let { logLine, time } = this.perf;
72
+ const executionTime = new Date() - time
73
+ this.totalTime += executionTime
74
+
75
+ const match = logLine.match(/^.*?BEGIN/);
76
+ const prepend = "END"
77
+ if (match) {
78
+ const toReplace = match[0]; // the matched substring
79
+ const spaces = " ".repeat(toReplace.length - prepend.length); // same length, all spaces
80
+ logLine = spaces + prepend + logLine.replace(toReplace, "");
81
+ }
82
+
83
+ this.loggers.perf('info', logLine + " (" + executionTime + "ms)")
84
+ }
85
+ return this
47
86
  }
48
87
 
49
88
  method(operation, name, options) {
89
+ if (operation != 'retrieve') this.manageEntry()
50
90
  const operations = {
51
91
  create: () => {
52
92
  this.savedMethods[name] = options
@@ -61,70 +101,91 @@ class Vaporous {
61
101
 
62
102
 
63
103
  operations[operation]()
64
- return this
104
+ if (operation !== 'retrieve') return this.manageExit()
105
+ return this;
106
+ }
107
+
108
+ filterIntoCheckpoint(checkpointName, funct, destroy) {
109
+ this.manageEntry()
110
+ const dataCheckpoint = this.events.filter(funct)
111
+ this._checkpoint('create', checkpointName, dataCheckpoint)
112
+ if (destroy) this.events = this.events.filter(event => !funct(event))
113
+ return this.manageExit()
65
114
  }
66
115
 
67
116
  filter(...args) {
117
+ this.manageEntry()
68
118
  this.events = this.events.filter(...args)
69
- return this
119
+ return this.manageExit()
70
120
  }
71
121
 
72
122
  append(entities) {
123
+ this.manageEntry()
73
124
  this.events = this.events.concat(entities)
74
- return this;
125
+ return this.manageExit()
75
126
  }
76
127
 
77
128
  eval(modifier) {
129
+ this.manageEntry()
78
130
  this.events.forEach(event => {
79
131
  const vals = modifier(event)
80
132
  if (vals) Object.assign(event, vals)
81
133
  })
82
- return this;
134
+ return this.manageExit()
83
135
  }
84
136
 
85
- table(modifier) {
137
+ _table(modifier) {
86
138
  this.events = this.events.map(event => {
87
139
  const vals = modifier(event)
88
140
  return vals;
89
141
  })
90
- return this;
142
+ }
143
+ table(modifier) {
144
+ this.manageEntry()
145
+ this._table(modifier)
146
+ return this.manageExit()
91
147
  }
92
148
 
93
149
  rename(...entities) {
150
+ this.manageEntry()
94
151
  this.events.forEach(event => {
95
152
  entities.forEach(([from, to]) => {
96
153
  event[to] = event[from]
97
154
  delete event[from]
98
155
  })
99
156
  })
100
- return this;
157
+ return this.manageExit()
101
158
  }
102
159
 
103
160
  parseTime(value, customFormat) {
161
+ this.manageEntry()
104
162
  this.events.forEach(event => {
105
163
  event[value] = dayjs(event[value], customFormat).valueOf()
106
164
  })
107
- return this;
165
+ return this.manageExit()
108
166
  }
109
167
 
110
168
  bin(value, span) {
169
+ this.manageEntry()
111
170
  this.events.forEach(event => {
112
171
  event[value] = Math.floor(event[value] / span) * span
113
172
  })
114
- return this;
173
+ return this.manageExit()
115
174
  }
116
175
 
117
176
  fileScan(directory) {
177
+ this.manageEntry()
118
178
  const items = fs.readdirSync(directory)
119
179
  this.events = items.map(item => {
120
180
  return {
121
181
  _fileInput: path.resolve(directory, item)
122
182
  }
123
183
  })
124
- return this;
184
+ return this.manageExit()
125
185
  }
126
186
 
127
187
  async csvLoad(parser) {
188
+ this.manageEntry()
128
189
  const tasks = this.events.map(obj => {
129
190
  const content = []
130
191
 
@@ -151,10 +212,11 @@ class Vaporous {
151
212
  })
152
213
 
153
214
  await Promise.all(tasks)
154
- return this;
215
+ return this.manageExit()
155
216
  }
156
217
 
157
218
  async fileLoad(delim, parser) {
219
+ this.manageEntry()
158
220
  const tasks = this.events.map(obj => {
159
221
  const content = []
160
222
 
@@ -178,10 +240,11 @@ class Vaporous {
178
240
  })
179
241
 
180
242
  await Promise.all(tasks)
181
- return this;
243
+ return this.manageExit()
182
244
  }
183
245
 
184
246
  output(...args) {
247
+ this.manageEntry()
185
248
  if (args.length) {
186
249
  console.log(this.events.map(event => {
187
250
  return args.map(item => event[item])
@@ -190,10 +253,11 @@ class Vaporous {
190
253
  console.log(this.events)
191
254
  }
192
255
 
193
- return this;
256
+ return this.manageExit()
194
257
  }
195
258
 
196
259
  flatten() {
260
+ this.manageEntry()
197
261
  const arraySize = this.events.reduce((acc, obj) => acc + obj._raw.length, 0)
198
262
  let flattened = new Array(arraySize)
199
263
  let i = 0
@@ -211,7 +275,7 @@ class Vaporous {
211
275
 
212
276
  })
213
277
  this.events = flattened;
214
- return this;
278
+ return this.manageExit()
215
279
  }
216
280
 
217
281
  _stats(args, events) {
@@ -268,11 +332,13 @@ class Vaporous {
268
332
  }
269
333
 
270
334
  stats(...args) {
335
+ this.manageEntry()
271
336
  this.events = this._stats(args, this.events).arr
272
- return this;
337
+ return this.manageExit()
273
338
  }
274
339
 
275
340
  eventstats(...args) {
341
+ this.manageEntry()
276
342
  const stats = this._stats(args, this.events)
277
343
 
278
344
  this.events.forEach(event => {
@@ -284,7 +350,7 @@ class Vaporous {
284
350
  return this
285
351
  }
286
352
 
287
- streamstats(...args) {
353
+ _streamstats(...args) {
288
354
  const backwardIterate = (event, i, by, maxBoundary = 0) => {
289
355
  let backwardIndex = 0
290
356
  const thisKey = keyFromEvent(event, by)
@@ -332,28 +398,38 @@ class Vaporous {
332
398
  delete event._streamstats
333
399
  })
334
400
 
335
- return this;
401
+ return this
402
+ }
403
+
404
+ streamstats(...args) {
405
+ this.manageEntry()
406
+ this._streamstats(...args)
407
+ return this.manageExit()
336
408
  }
337
409
 
338
410
  delta(field, remapField, ...bys) {
339
- this.streamstats(new Aggregation(field, 'range', remapField), new Window(2), ...bys)
340
- return this;
411
+ this.manageEntry()
412
+ this._streamstats(new Aggregation(field, 'range', remapField), new Window(2), ...bys)
413
+ return this.manageExit()
341
414
  }
342
415
 
343
416
  sort(order, ...keys) {
417
+ this.manageEntry()
344
418
  this.events = _sort(order, this.events, ...keys)
345
- return this;
419
+ return this.manageExit()
346
420
  }
347
421
 
348
422
  assert(funct) {
423
+ this.manageEntry()
349
424
  const expect = (funct) => { if (!funct) throw new Error('Assertion failed') }
350
425
  this.events.forEach((event, i) => {
351
426
  funct(event, i, { expect })
352
427
  })
353
- return this;
428
+ return this.manageExit()
354
429
  }
355
430
 
356
- build(name, type, { tab = 'Default', columns = 2, y2, y1Type, y2Type, y1Stacked, y2Stacked, sortX = 'asc', xTicks = false, trellisAxis = "shared" } = {}) {
431
+ build(name, type, { tab = 'Default', columns = 2, y2, y1Type, y2Type, y1Stacked, y2Stacked, sortX = 'asc', xTicks = false, trellisAxis = "shared", legend } = {}) {
432
+ this.manageEntry()
357
433
 
358
434
  const visualisationOptions = { tab, columns }
359
435
 
@@ -468,6 +544,7 @@ class Vaporous {
468
544
  responsive: true,
469
545
  plugins: {
470
546
  legend: {
547
+ display: legend || true,
471
548
  position: 'bottom',
472
549
  },
473
550
  title: {
@@ -511,22 +588,29 @@ class Vaporous {
511
588
  this.tabs = this.tabs.sort((a, b) => a.localeCompare(b))
512
589
  }
513
590
 
514
- return this;
591
+ return this.manageExit()
515
592
  }
516
593
 
517
- checkpoint(operation, name) {
594
+ _checkpoint(operation, name, data) {
518
595
 
519
596
  const operations = {
520
- create: () => this.checkpoints[name] = structuredClone(this.events),
597
+ create: () => this.checkpoints[name] = structuredClone(data),
521
598
  retrieve: () => this.events = structuredClone(this.checkpoints[name]),
522
599
  delete: () => delete this.checkpoints[name]
523
600
  }
524
601
 
525
602
  operations[operation]()
526
- return this;
603
+ return this
604
+ }
605
+
606
+ checkpoint(operation, name) {
607
+ this.manageEntry()
608
+ this._checkpoint(operation, name, this.events)
609
+ return this.manageExit()
527
610
  }
528
611
 
529
612
  mvexpand(target) {
613
+ this.manageEntry()
530
614
  const arr = []
531
615
  this.events.forEach(event => {
532
616
  if (!event[target]) return arr.push(event)
@@ -540,32 +624,33 @@ class Vaporous {
540
624
  })
541
625
 
542
626
  this.events = arr
543
- return this;
627
+ return this.manageExit()
544
628
  }
545
629
 
546
630
  writeFile(title) {
631
+ this.manageEntry()
547
632
  fs.writeFileSync('./' + title, JSON.stringify(this.events))
548
- return this;
633
+ return this.manageExit()
549
634
  }
550
635
 
551
636
  toGraph(x, y, series, trellis = false) {
552
-
637
+ this.manageEntry()
553
638
  if (!(y instanceof Array)) y = [y]
554
639
 
555
640
  const yAggregations = y.map(item => [
556
641
  new Aggregation(item, 'list', item),
557
642
  ]).flat()
558
643
 
559
- this.stats(
644
+ this.events = this._stats([
560
645
  ...yAggregations,
561
646
  new Aggregation(series, 'list', series),
562
647
  new Aggregation(trellis, 'values', 'trellis'),
563
- new By(x), trellis ? new By(trellis) : null
564
- )
648
+ new By(x), trellis ? new By(trellis) : null], this.events
649
+ ).arr
565
650
 
566
651
  const trellisMap = {}, columnDefinitions = {}
567
652
 
568
- this.table(event => {
653
+ this._table(event => {
569
654
  const _time = event[x]
570
655
  if (_time === null || _time === undefined) throw new Error(`To graph operation with params ${x}, ${y.join(',')} looks corrupt. x value resolves to null - the graph will not render`)
571
656
  const obj = {
@@ -625,10 +710,11 @@ class Vaporous {
625
710
  }
626
711
 
627
712
  this.graphFlags.push(graphFlags)
628
- return this;
713
+ return this.manageExit()
629
714
  }
630
715
 
631
716
  render(location = './Vaporous_generation.html') {
717
+ this.manageEntry()
632
718
  const classSafe = (name) => name.replace(/[^a-zA-Z0-9]/g, "_")
633
719
 
634
720
  const createElement = (name, type, visualisationOptions, eventData, { trellis, trellisName = "" }) => {
@@ -719,8 +805,9 @@ class Vaporous {
719
805
  </body>
720
806
  </html>
721
807
  `)
722
-
723
808
  console.log('File ouput created ', path.resolve(filePath))
809
+ if (this.totalTime) console.log("File completed in " + this.totalTime)
810
+ return this.manageExit()
724
811
  }
725
812
  }
726
813
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vaporous",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "description": "Transition data to different structured states for analytical processing",
5
5
  "main": "Vaporous.js",
6
6
  "scripts": {
package/styles.css CHANGED
@@ -61,7 +61,7 @@ body {
61
61
  flex-wrap: wrap;
62
62
  padding: 0px;
63
63
  gap: 8px;
64
- justify-content: space-between;
64
+ justify-content: flex-start;
65
65
  }
66
66
 
67
67
  .parentHolder {