index.js 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import { domReady, buildInitExpression, isNullOrUndefined } from './utils'
  2. import { createObservable } from './observable'
  3. import EventBus from './bus'
  4. const Spruce = {
  5. options: {
  6. globalStoreVariable: false,
  7. },
  8. events: EventBus,
  9. stores: {},
  10. subscribers: [],
  11. start: async function () {
  12. await domReady()
  13. this.emit('init')
  14. document.querySelectorAll('[x-subscribe]').forEach(el => {
  15. el.setAttribute('x-init', buildInitExpression(el))
  16. el.removeAttribute('x-subscribe')
  17. })
  18. this.stores = createObservable(this.stores, {
  19. set: (target, key, value, oldValue) => {
  20. this.events.runWatchers(this.stores, target, key, oldValue)
  21. this.updateSubscribers()
  22. }
  23. })
  24. if (this.options.globalStoreVariable) {
  25. document.querySelectorAll('[x-data]').forEach(el => {
  26. if (! this.subscribers.includes(el)) {
  27. this.subscribers.push(el)
  28. }
  29. })
  30. window.$store = this.stores
  31. }
  32. },
  33. store: function (name, state) {
  34. if (! this.stores[name]) {
  35. this.stores[name] = state
  36. }
  37. return this.stores[name]
  38. },
  39. reset: function (name, state) {
  40. this.stores[name] = state
  41. this.updateSubscribers()
  42. },
  43. subscribe(el) {
  44. this.subscribers.push(el)
  45. return this.stores
  46. },
  47. updateSubscribers() {
  48. this.subscribers.forEach(el => {
  49. if (el.__x !== undefined) {
  50. el.__x.updateElements(el)
  51. }
  52. })
  53. },
  54. config(options = {}) {
  55. this.options = Object.assign(this.options, options)
  56. },
  57. on(name, callback) {
  58. return this.events.on(name, callback)
  59. },
  60. off(name, callback) {
  61. this.events.off(name, callback)
  62. },
  63. emit(name, data = {}) {
  64. this.events.emit(name, { ...data, store: this.stores })
  65. },
  66. watch(dotNotation, callback) {
  67. this.events.watch(dotNotation, callback)
  68. }
  69. }
  70. const deferrer = window.deferLoadingAlpine || function (callback) { callback() }
  71. window.deferLoadingAlpine = function (callback) {
  72. window.Spruce = Spruce
  73. window.Spruce.start()
  74. deferrer(callback)
  75. }
  76. export default Spruce