@iebh/tera-fy 1.0.8 → 1.0.9

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.
@@ -64,6 +64,9 @@ export default class TeraFy {
64
64
  'getProjectState', 'applyProjectStatePatch',
65
65
  // bindProjectState() - See below
66
66
 
67
+ // Project files
68
+ 'getProjectFiles',
69
+
67
70
  // Project Libraries
68
71
  'getProjectLibrary', 'setProjectLibrary',
69
72
  ];
@@ -434,6 +434,63 @@ export default class TeraFyServer {
434
434
  this.debug('Applying sever state patch', {patch});
435
435
  }
436
436
 
437
+
438
+
439
+ /**
440
+ * Subscribers to server project state changes
441
+ * @type {Array<Object>}}
442
+ * @property {String} id A unique ID for this subscriber state
443
+ * @property {String} source The human readable source for each subscriber
444
+ * @property {Function} sendPatch Function used to send a patch to a subscriber
445
+ * @property {Function} unsubscribe Function to release the client subscription
446
+ */
447
+ projectStateSubscribers = [];
448
+ // }}}
449
+
450
+ // Project files - getProjectFiles() {{{
451
+
452
+ /**
453
+ * Data structure for a project file
454
+ * @class ProjectFile
455
+ *
456
+ * @property {String} id A UUID string representing the unique ID of the file
457
+ * @property {String} name Relative name path (can contain prefix directories) for the human readable file name
458
+ * @property {Object} parsedName An object representing meta file parts of a file name
459
+ * @property {String} parsedName.basename The filename + extention (i.e. everything without directory name)
460
+ * @property {String} parsedName.filename The file portion of the name (basename without the extension)
461
+ * @property {String} parsedName.ext The extension portion of the name (always lower case)
462
+ * @property {String} parsedName.dirName The directory path portion of the name
463
+ * @property {Date} created A date representing when the file was created
464
+ * @property {Date} modified A date representing when the file was created
465
+ * @property {Date} accessed A date representing when the file was last accessed
466
+ * @property {Number} size Size, in bytes, of the file
467
+ * @property {String} mime The associated mime type for the file
468
+ */
469
+
470
+
471
+ /**
472
+ * Fetch the files associated with a given project
473
+ *
474
+ * @param {Object} options Options which mutate behaviour
475
+ * @param {Boolean} [options.autoRequire=true] Run `requireProject()` automatically before continuing
476
+ * @param {Boolean} [options.meta=true] Pull meta information for each file entity
477
+ *
478
+ * @returns {Promise<ProjectFile>} A collection of project files for the given project
479
+ */
480
+ getProjectFiles(options) {
481
+ let settings = {
482
+ autoRequire: true,
483
+ meta: true,
484
+ ...options,
485
+ };
486
+
487
+ return Promise.resolve()
488
+ .then(()=> app.service('$projects').promise())
489
+ .then(()=> settings.autoRequire && this.requireProject())
490
+ .then(project => app.service('$supabase').fileList(`/projects/${project.id}`, {
491
+ meta: settings.meta,
492
+ }))
493
+ }
437
494
  // }}}
438
495
 
439
496
  // Project Libraries - getProjectLibrary(), setProjectLibrary() {{{
@@ -441,24 +498,47 @@ export default class TeraFyServer {
441
498
  /**
442
499
  * Fetch the active projects citation library
443
500
  *
501
+ * @param {String} [path] Optional file path to use, if omitted the contents of `options` are used to guess at a suitable file
444
502
  * @param {Object} [options] Additional options to mutate behaviour
445
503
  * @param {Boolean} [options.autoRequire=true] Run `requireProject()` automatically before continuing
446
504
  * @param {Boolean} [options.multiple=false] Allow selection of multiple libraries
505
+ * @param {Function} [options.filter] Optional async file filter, called each time as `(File:ProjectFile)`
506
+ * @param {Function} [options.find] Optional async final stage file filter to reduce all candidates down to one subject file
447
507
  * @param {String|Array<String>} [options.hint] Hints to identify the library to select in array order of preference. Generally corresponds to the previous stage - e.g. 'deduped', 'review1', 'review2', 'dedisputed'
448
508
  *
449
- * @returns {Promise<Array<RefLibRef>>} Collection of references for the selected library
509
+ * @returns {Promise<Array<ProjectFile>>} Collection of references for the selected library matching the given hint + filter, this could be a zero length array
450
510
  */
451
- getProjectLibrary(options) {
511
+ getProjectLibrary(path, options) {
452
512
  let settings = {
513
+ path,
453
514
  autoRequire: true,
454
515
  multiple: false,
455
516
  hint: null,
456
- ...options,
517
+ filter: file => true,
518
+ find: files => files.at(0),
519
+ ...(typeof path == 'string' ? {path, ...options} : path),
457
520
  };
458
521
 
459
522
  return Promise.resolve()
460
- .then(()=> settings.autoRequire && this.requireProject())
461
- // FIXME: Stub
523
+ .then(()=> {
524
+ if (settings.path) { // Already have a file name picked
525
+ if (!settings.path.startsWith('/')) throw new Error('All file names must start with a forward slash');
526
+ return settings.path;
527
+ } else { // Try to guess the file from the options structure
528
+ return this.getProjectFiles({
529
+ autoRequire: settings.autoRequire,
530
+ })
531
+ .then(files => files.filter(file =>
532
+ settings.filter(file)
533
+ ))
534
+ .then(files => settings.find(files))
535
+ .then(file => file.path)
536
+ }
537
+ })
538
+ .then(filePath => app.service('$supabase').fileGet(filePath, {
539
+ json: true,
540
+ toast: false,
541
+ }))
462
542
  }
463
543
 
464
544
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iebh/tera-fy",
3
- "version": "1.0.8",
3
+ "version": "1.0.9",
4
4
  "description": "TERA website worker",
5
5
  "scripts": {
6
6
  "dev": "esbuild --platform=browser --format=esm --bundle lib/terafy.client.js --outfile=dist/terafy.js --minify --sourcemap --serve --servedir=.",