flux.js 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. // Experimental
  2. var flux = flux || {};
  3. var json = json || require('./json');
  4. flux.ModelFactory = class {
  5. match(context) {
  6. const identifier = context.identifier;
  7. const extension = identifier.split('.').pop().toLowerCase();
  8. const stream = context.stream;
  9. if (stream && extension === 'bson') {
  10. return 'flux.bson';
  11. }
  12. return undefined;
  13. }
  14. open(context) {
  15. return Promise.resolve().then(() => {
  16. let root = null;
  17. try {
  18. const stream = context.stream;
  19. const reader = json.BinaryReader.open(stream);
  20. root = reader.read();
  21. }
  22. catch (error) {
  23. const message = error && error.message ? error.message : error.toString();
  24. throw new flux.Error('File format is not Flux BSON (' + message.replace(/\.$/, '') + ').');
  25. }
  26. return context.metadata('flux-metadata.json').then((metadata) => {
  27. const obj = flux.ModelFactory._backref(root, root);
  28. const model = obj.model;
  29. if (!model) {
  30. throw new flux.Error('File does not contain Flux model.');
  31. }
  32. return new flux.Model(metadata, model);
  33. });
  34. });
  35. }
  36. static _backref(obj, root) {
  37. if (Array.isArray(obj)) {
  38. for (let i = 0; i < obj.length; i++) {
  39. obj[i] = flux.ModelFactory._backref(obj[i], root);
  40. }
  41. }
  42. else if (obj === Object(obj)) {
  43. if (obj.tag == 'backref' && obj.ref) {
  44. if (!root._backrefs[obj.ref - 1]) {
  45. throw new flux.Error("Invalid backref '" + obj.ref + "'.");
  46. }
  47. obj = root._backrefs[obj.ref - 1];
  48. }
  49. for (const key of Object.keys(obj)) {
  50. if (obj !== root || key !== '_backrefs') {
  51. obj[key] = flux.ModelFactory._backref(obj[key], root);
  52. }
  53. }
  54. }
  55. return obj;
  56. }
  57. };
  58. flux.Model = class {
  59. constructor(/* root */) {
  60. this._format = 'Flux';
  61. this._graphs = [];
  62. }
  63. get format() {
  64. return this._format;
  65. }
  66. get graphs() {
  67. return this._graphs;
  68. }
  69. };
  70. flux.Error = class extends Error {
  71. constructor(message) {
  72. super(message);
  73. this.name = 'Flux Error';
  74. }
  75. };
  76. if (module && module.exports) {
  77. module.exports.ModelFactory = flux.ModelFactory;
  78. }