@cocreate/file 1.17.0 → 1.17.2

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/CHANGELOG.md +17 -0
  2. package/package.json +14 -14
  3. package/src/client.js +182 -49
package/CHANGELOG.md CHANGED
@@ -1,3 +1,20 @@
1
+ ## [1.17.2](https://github.com/CoCreate-app/CoCreate-file/compare/v1.17.1...v1.17.2) (2024-04-29)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * bump cocreate dependencies ([6034fc5](https://github.com/CoCreate-app/CoCreate-file/commit/6034fc570aade211662c77aaf6d66ea2c11a7340))
7
+
8
+ ## [1.17.1](https://github.com/CoCreate-app/CoCreate-file/compare/v1.17.0...v1.17.1) (2024-04-26)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * condition to check input.ProcessFIle exists ([478d652](https://github.com/CoCreate-app/CoCreate-file/commit/478d65274f52ac8c0de9341ee5ca1766e0542f7f))
14
+ * getFiles returns files as is without conversion ([ad57ce3](https://github.com/CoCreate-app/CoCreate-file/commit/ad57ce3895c4246268b49b192d69e2bae09cf0c7))
15
+ * method set to static object.update ([27dbf8e](https://github.com/CoCreate-app/CoCreate-file/commit/27dbf8e717a4bc5ffd5c2f6a6bae28e081e8a7b2))
16
+ * replaced keyword spaces with hyphens and lowercase letters only ([77f9d89](https://github.com/CoCreate-app/CoCreate-file/commit/77f9d896ded45e1341d58faa6973d58198a4e308))
17
+
1
18
  # [1.17.0](https://github.com/CoCreate-app/CoCreate-file/compare/v1.16.0...v1.17.0) (2024-03-18)
2
19
 
3
20
 
package/package.json CHANGED
@@ -1,18 +1,18 @@
1
1
  {
2
2
  "name": "@cocreate/file",
3
- "version": "1.17.0",
3
+ "version": "1.17.2",
4
4
  "description": "A versatile, configurable headless file uploader supporting both local and server file operations. Accessible via a JavaScript API and HTML5 attributes, it offers seamless file reading, writing, and uploading capabilities with graceful fallbacks to the standard HTML5 file input API. Ideal for developers requiring robust file management in headless or UI-less environments.",
5
5
  "keywords": [
6
- "file uploader",
6
+ "file-uploader",
7
7
  "headless",
8
- "HTML5 attributes",
9
- "server upload",
10
- "customizable uploader",
11
- "file upload API",
12
- "no UI upload",
13
- "background file upload",
14
- "programmatic file upload",
15
- "headless file management",
8
+ "html5-attributes",
9
+ "server-upload",
10
+ "customizable-uploader",
11
+ "file-upload-api",
12
+ "no-ui-upload",
13
+ "background-file-upload",
14
+ "programmatic-file-upload",
15
+ "headless-file-management",
16
16
  "cocreate",
17
17
  "low-code-framework",
18
18
  "cocreatejs",
@@ -63,9 +63,9 @@
63
63
  "webpack-log": "^3.0.1"
64
64
  },
65
65
  "dependencies": {
66
- "@cocreate/actions": "^1.14.0",
67
- "@cocreate/config": "^1.8.0",
68
- "@cocreate/render": "^1.35.0",
69
- "@cocreate/utils": "^1.29.0"
66
+ "@cocreate/actions": "^1.18.1",
67
+ "@cocreate/config": "^1.12.2",
68
+ "@cocreate/render": "^1.40.3",
69
+ "@cocreate/utils": "^1.33.6"
70
70
  }
71
71
  }
package/src/client.js CHANGED
@@ -150,6 +150,11 @@ async function fileEvent(event) {
150
150
 
151
151
  if (!files[i].src)
152
152
  await readFile(files[i])
153
+ // if (!files[i].src)
154
+ // files[i].src = files[i]
155
+
156
+ // if (!files[i].src.name)
157
+ // files[i].src = files[i]
153
158
 
154
159
  if (!files[i].size)
155
160
  files[i].size = handle.size
@@ -173,7 +178,7 @@ async function fileEvent(event) {
173
178
  console.log("Files selected:", selected);
174
179
 
175
180
  if (input.renderValue)
176
- input.renderValue(Array.from(selected.values()))
181
+ input.renderValue(Array.from(selected.values()));
177
182
 
178
183
  const isImport = input.getAttribute('import')
179
184
  const isRealtime = input.getAttribute('realtime')
@@ -226,7 +231,7 @@ async function getFileId(file) {
226
231
  }
227
232
  }
228
233
 
229
- async function getFiles(fileInputs) {
234
+ async function getFiles(fileInputs, readAs) {
230
235
  const files = [];
231
236
 
232
237
  if (!Array.isArray(fileInputs))
@@ -236,8 +241,13 @@ async function getFiles(fileInputs) {
236
241
  const selected = inputs.get(input)
237
242
  if (selected) {
238
243
  for (let file of Array.from(selected.values())) {
239
- if (!file.src)
240
- await readFile(file)
244
+ if (!file.src) {
245
+ // if (readAs === 'blob')
246
+ file.src = file
247
+ // else
248
+ // await readFile(file, readAs)
249
+ }
250
+
241
251
  let fileObject = { ...file }
242
252
  fileObject.size = file.size
243
253
  await getCustomData(fileObject)
@@ -251,6 +261,7 @@ async function getFiles(fileInputs) {
251
261
  }
252
262
 
253
263
  async function getCustomData(file) {
264
+ // TODO: Consider potential replacment of file_id, perhaps supporting selector
254
265
  let form = document.querySelector(`[file_id="${file.id}"]`);
255
266
  if (form) {
256
267
  let elements = form.querySelectorAll('[file]');
@@ -268,13 +279,15 @@ async function getCustomData(file) {
268
279
  }
269
280
 
270
281
  // This function reads the file and returns its src
271
- function readFile(file) {
282
+ function readFile(file, readAs) {
272
283
  return new Promise((resolve) => {
273
284
  const fileType = file.type.split('/');
274
- let readAs;
275
285
 
276
286
  if (fileType[1] === 'directory') {
277
287
  return resolve(file)
288
+ } else if (readAs) {
289
+ if (readAs === 'blob')
290
+ return resolve(file)
278
291
  } else if (fileType[0] === 'image') {
279
292
  readAs = 'readAsDataURL';
280
293
  } else if (fileType[0] === 'video') {
@@ -321,6 +334,7 @@ function setFiles(element, files) {
321
334
  render({ source: element, data: Array.from(selected.values()) })
322
335
  }
323
336
 
337
+ // TODO: Could this benifit from media processing to save results locally
324
338
  async function save(element, action, data) {
325
339
  try {
326
340
  if (!data)
@@ -410,26 +424,25 @@ async function upload(element, data) {
410
424
  element = [element]
411
425
 
412
426
  for (let i = 0; i < element.length; i++) {
413
- const inputs = []
427
+ const fileInputs = []
414
428
  if (element[i].type === 'file')
415
- inputs.push(element[i])
429
+ fileInputs.push(element[i])
416
430
  else if (element[i].tagName === 'form') {
417
- let fileInputs = element[i].querySelectorAll('input[type="file"]')
418
- inputs.push(...fileInputs)
431
+ fileInputs.push(...element[i].querySelectorAll('input[type="file"]'))
419
432
  } else {
420
433
  const form = element[i].closest('form')
421
434
  if (form)
422
- inputs.push(...form.querySelectorAll('input[type="file"]'))
435
+ fileInputs.push(...form.querySelectorAll('input[type="file"]'))
423
436
  }
424
437
 
425
- for (let input of inputs) {
438
+ for (let input of fileInputs) {
426
439
  let Data = Elements.getObject(input);
427
- let key = getAttribute('key')
428
- if (Data.type === 'key')
429
- Data.type = 'object'
440
+ let object = input.getAttribute('object') || ''
441
+ let key = input.getAttribute('key')
430
442
 
431
- Data.method = Data.type + '.update'
432
- if (Data.array)
443
+ Data.broadcastBrowser = false
444
+ Data.method = 'object.update'
445
+ if (!Data.array)
433
446
  Data.array = 'files'
434
447
 
435
448
  let path = input.getAttribute('path')
@@ -438,11 +451,17 @@ async function upload(element, data) {
438
451
  if (path) {
439
452
  directory = path.split('/');
440
453
  directory = directory[directory.length - 1];
441
- if (!path.endswith('/'))
454
+ if (!path.endsWith('/'))
442
455
  path += '/'
443
456
  } else
444
457
  path = directory = '/'
445
458
 
459
+ if (!Data.host)
460
+ Data.host = ['*']
461
+
462
+ if (!Data.public)
463
+ Data.public = true
464
+
446
465
  if (input.getFilter) {
447
466
  Data.$filter = await input.getFilter()
448
467
  if (!Data.$filter.query)
@@ -453,50 +472,163 @@ async function upload(element, data) {
453
472
  }
454
473
 
455
474
 
456
- let files = await getFiles(input)
475
+ // let files = await getFiles(input, 'blob')
476
+ let files
477
+ const selected = inputs.get(input)
478
+ if (selected) {
479
+ files = Array.from(selected.values())
480
+ }
481
+
457
482
  let segmentSize = 10 * 1024 * 1024
458
483
  for (let i = 0; i < files.length; i++) {
459
484
  files[i].path = path
460
- files[i].pathname = path + '/' + files[i].name
485
+ files[i].pathname = path + files[i].name
461
486
  files[i].directory = directory
462
487
 
488
+ // let fileObject = { ...file }
489
+ // fileObject.size = file.size
490
+ // await getCustomData(fileObject)
491
+
463
492
 
464
- if (files[i].size > segmentSize) {
465
- let { streamConfig, segments } = await processFile(files[i], null, segmentSize);
466
- files[i].src = streamConfig
467
- for (let j = 0; j < segments.length; j++) {
468
- segments[j].path = path
469
- segments[j].pathname = path + '/' + segments[j].name
470
- segments[j].directory = directory
493
+ if (input.processFile && files[i].size > segmentSize) {
494
+ // let test = await input.processFile(files[i], null, segmentSize, null, null, null, input);
495
+ let { playlist, segments } = await input.processFile(files[i], null, segmentSize);
471
496
 
472
- Data.$filter.query.pathname = segments[j].pathname
473
- Crud.send({
474
- ...Data,
475
- object: segments[j],
476
- upsert: true
497
+ // Create a video element
498
+ const videoElement = document.createElement('video');
499
+ videoElement.setAttribute('controls', ''); // Add controls so you can play/pause
500
+ videoElement.style.width = '100%';
501
+ document.body.appendChild(videoElement);
502
+
503
+ const mediaSource = new MediaSource();
504
+ videoElement.src = URL.createObjectURL(mediaSource);
505
+
506
+ mediaSource.addEventListener('sourceopen', () => {
507
+ const sourceBuffer = mediaSource.addSourceBuffer('video/mp4; codecs="avc1.42E01E"');
508
+
509
+ sourceBuffer.addEventListener('updateend', () => {
510
+ console.log('Append operation completed.');
511
+ try {
512
+ console.log('Buffered ranges:', sourceBuffer.buffered);
513
+ // Append next segment here if applicable
514
+ } catch (e) {
515
+ console.error('Error accessing buffered property:', e);
516
+ }
477
517
  });
478
- }
479
518
 
480
- }
481
- }
519
+ function appendSegment(index) {
520
+ if (index >= segments.length) {
521
+ console.log('All segments have been appended.');
522
+ return;
523
+ }
524
+
525
+ if (!sourceBuffer.updating) {
526
+ segments[index].src.arrayBuffer().then(arrayBuffer => {
527
+ console.log(`Appending segment ${index}`);
528
+ sourceBuffer.appendBuffer(arrayBuffer);
529
+ // Next segment will be appended on 'updateend' event
530
+ }).catch(error => {
531
+ console.error(`Error reading segment[${index}] as ArrayBuffer:`, error);
532
+ });
533
+ }
534
+ }
535
+
536
+ // Append the first segment to start
537
+ appendSegmfent(0);
538
+ });
482
539
 
483
- let object = input.getAttribute('object')
484
- if (key) {
485
- Data[Data.type] = { _id: object, [key]: files }
486
- } else {
487
- Data[Data.type] = files
488
- }
489
540
 
490
- // Data.$filter.query.pathname = files[i].pathname
541
+ // mediaSource.addEventListener('sourceopen', () => {
542
+ // const sourceBuffer = mediaSource.addSourceBuffer('video/mp4; codecs="avc1.42E01E"'); // avc1.4D401E, avc1.4D401F, avc1.4D4028, avc1.4D4020, avc1.4D4029, avc1.4D402A
543
+
544
+ // // Append the first segment to start
545
+ // if (!sourceBuffer.updating) {
546
+
547
+ // segments[0].src.arrayBuffer().then(arrayBuffer => {
548
+ // sourceBuffer.appendBuffer(arrayBuffer);
549
+
550
+ // // Wait for 3 seconds before logging the sourceBuffer state
551
+ // setTimeout(() => {
552
+ // console.log(sourceBuffer);
553
+ // }, 3000); // 3000 milliseconds = 3 seconds
554
+
555
+ // sourceBuffer.addEventListener('updateend', () => {
556
+ // console.log('Append operation completed.');
557
+ // try {
558
+ // console.log('Buffered ranges:', sourceBuffer.buffered);
559
+ // } catch (e) {
560
+ // console.error('Error accessing buffered property:', e);
561
+ // }
562
+ // // Proceed with additional operations here
563
+ // });
564
+
565
+ // }).catch(error => {
566
+ // console.error('Error reading segment[0] as ArrayBuffer:', error);
567
+ // });
568
+
569
+
570
+ // // segments[0].src.arrayBuffer().then(arrayBuffer => {
571
+ // // sourceBuffer.appendBuffer(arrayBuffer);
572
+ // // })
573
+
574
+ // // let segmentLength = 0
575
+ // // sourceBuffer.addEventListener('updateend', () => {
576
+ // // segmentLength += 1
577
+ // // if (segments[segmentLength])
578
+ // // segments[segmentLength].src.arrayBuffer().then(arrayBuffer => {
579
+ // // console.log(sourceBuffer)
580
+ // // // sourceBuffer.appendBuffer(arrayBuffer);
581
+ // // })
582
+ // // });
583
+ // }
584
+ // });
585
+
586
+ }
491
587
 
492
- let response = await Crud.send({
493
- ...Data,
494
- upsert: true
495
- });
588
+ // files[i].src = playlist
589
+ // for (let j = 0; j < segments.length; j++) {
590
+ // segments[j].path = path
591
+ // segments[j].pathname = path + segments[j].name
592
+ // segments[j].directory = directory
593
+ // segments[j] = { ...segments[j], ...await readFile(segments[j].src) }
594
+ // segments[j].public = true
595
+ // segments[j].host = ['*']
596
+
597
+ // playlist.segments[j].src = segments[j].pathname
598
+ // Data.$filter.query.pathname = segments[j].pathname
599
+ // Crud.send({
600
+ // ...Data,
601
+ // object: segments[j],
602
+ // upsert: true
603
+ // });
604
+ // }
605
+
606
+ // } else {
607
+ // files[i] = { ...files[i], ...await readFile(files[i].src) }
608
+ // }
609
+
610
+ // if (!key) {
611
+ // Data.object = { ...files[i] }
612
+ // } else {
613
+ // Data.object = { [key]: { ...files[i] } }
614
+ // }
615
+
616
+ // if (object) {
617
+ // Data.object._id = object // test
618
+ // }
619
+
620
+ // delete Data.object.input
621
+ // Data.$filter.query.pathname = files[i].pathname
622
+ // let response = await Crud.send({
623
+ // ...Data,
624
+ // upsert: true
625
+ // });
626
+
627
+ // console.log(response, 'tes')
628
+ // if (response && (!object || object !== response.object)) {
629
+ // Elements.setTypeValue(element, response);
630
+ // }
496
631
 
497
- data.push(response)
498
- if (response && (!object || object !== response.object)) {
499
- Elements.setTypeValue(element, response);
500
632
  }
501
633
  }
502
634
 
@@ -560,6 +692,7 @@ async function Import(element, data) {
560
692
 
561
693
  if (data.length) {
562
694
  for (let i = 0; i < data.length; i++) {
695
+ // TODO: if _id exist use update method
563
696
  data[i].method = data[i].type + '.create'
564
697
  data[i] = await Crud.send(data[i])
565
698
  }