lookbook 1.0.3 → 1.0.8

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 (36) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/lookbook/js/app.js +1 -0
  3. data/app/assets/lookbook/js/lib/socket.js +9 -5
  4. data/app/components/lookbook/base_component.rb +10 -2
  5. data/app/components/lookbook/copy_button/component.rb +1 -1
  6. data/app/components/lookbook/dimensions_display/component.rb +1 -4
  7. data/app/components/lookbook/embed/component.rb +1 -1
  8. data/app/components/lookbook/icon/component.rb +1 -5
  9. data/app/components/lookbook/nav/component.html.erb +1 -1
  10. data/app/components/lookbook/nav/item/component.rb +2 -2
  11. data/app/components/lookbook/params_editor/field/component.rb +1 -1
  12. data/app/components/lookbook/tabs/component.js +2 -2
  13. data/app/controllers/lookbook/application_controller.rb +10 -1
  14. data/app/controllers/lookbook/pages_controller.rb +0 -1
  15. data/app/controllers/lookbook/previews_controller.rb +9 -6
  16. data/app/helpers/lookbook/component_helper.rb +2 -1
  17. data/app/views/layouts/lookbook/application.html.erb +6 -36
  18. data/app/views/lookbook/index.html.erb +2 -2
  19. data/app/views/lookbook/previews/show.html.erb +1 -1
  20. data/config/routes.rb +1 -1
  21. data/lib/lookbook/config.rb +7 -3
  22. data/lib/lookbook/data.rb +2 -2
  23. data/lib/lookbook/engine.rb +34 -50
  24. data/lib/lookbook/parser.rb +19 -11
  25. data/lib/lookbook/preview.rb +22 -76
  26. data/lib/lookbook/preview_controller.rb +19 -1
  27. data/lib/lookbook/preview_example.rb +12 -5
  28. data/lib/lookbook/source_inspector.rb +2 -2
  29. data/lib/lookbook/store.rb +2 -2
  30. data/lib/lookbook/version.rb +1 -1
  31. data/lib/tasks/lookbook_tasks.rake +1 -2
  32. data/public/lookbook-assets/css/lookbook.css +8 -34
  33. data/public/lookbook-assets/css/lookbook.css.map +1 -1
  34. data/public/lookbook-assets/js/lookbook.js +174 -120
  35. data/public/lookbook-assets/js/lookbook.js.map +1 -1
  36. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 741dcc6296e79ba365a64945fb70b7ba7e8b8df2eee9e83e72ef4e32c619b2fc
4
- data.tar.gz: aa5d6647abc755e54b37837847f5929803eba7545272e6c33b887f2f7c5ef54e
3
+ metadata.gz: 95694c758af19ee6a561b2aedfee93d932c663f7027471204da2dce393052a5a
4
+ data.tar.gz: 1b4f3e4af714af47b6719cbbef7a861ad0ca2341089e2689ef8ed80b9a745867
5
5
  SHA512:
6
- metadata.gz: d19a7567121be4be2c010f61d9c7d62ecff33d53d034a138124516883cbb190102aa0f8c9e9457a0aaf1d33c6d9d5250d3a60ad507af9973348f3c08c03c26bb
7
- data.tar.gz: 8cc77046623125e88550cfd7ff4dd626a2deda064fee6cf3171d5a5cd59bed8ec2277e8091d48d995763db7b3fe66c730e99bde1380a4e5703986e7cc0808ff4
6
+ metadata.gz: 0a148ae5b71546463c003244040e54de07106db6f927e61b77ff35c92d524f37ed59e53646833675a8d1c399968904ffe41891817e85628aa8da879af8aa3bd8
7
+ data.tar.gz: ee91d909da4634558dbf542802ee770c921f0dfdec0bdc37592977b082a97705957bf7e19cf5168b599e78dca1f5d4222147417262c4b41f90b305a43c2c4f72
@@ -11,6 +11,7 @@ export default function app() {
11
11
 
12
12
  init() {
13
13
  if (window.SOCKET_PATH) {
14
+ console.log("SOCKET CREATED");
14
15
  const socket = createSocket(window.SOCKET_PATH);
15
16
  socket.addListener("Lookbook::ReloadChannel", () => this.updateDOM());
16
17
  }
@@ -1,5 +1,5 @@
1
1
  import { createConsumer } from "@rails/actioncable";
2
- import debounce from "debounce";
2
+ import { debounce } from "throttle-debounce";
3
3
  import { log } from "../plugins/logger";
4
4
 
5
5
  export default function socket(endpoint) {
@@ -8,10 +8,14 @@ export default function socket(endpoint) {
8
8
  return {
9
9
  addListener(channel, callback) {
10
10
  consumer.subscriptions.create(channel, {
11
- received: debounce((data) => {
12
- log.debug("Lookbook files changed");
13
- callback(data);
14
- }, 200),
11
+ received: debounce(
12
+ 200,
13
+ (data) => {
14
+ log.debug("Lookbook files changed");
15
+ callback(data);
16
+ },
17
+ { atBegin: true }
18
+ ),
15
19
  connected() {
16
20
  log.info("Lookbook websocket connected");
17
21
  },
@@ -31,11 +31,19 @@ module Lookbook
31
31
  nil
32
32
  end
33
33
 
34
+ def alpine_encode(data)
35
+ if data.is_a? String
36
+ "\'#{json_escape data}\'"
37
+ else
38
+ json_escape data.to_json.tr("\"", "\'")
39
+ end
40
+ end
41
+
34
42
  def prepare_alpine_data(x_data = nil)
35
43
  alpine_component_name = x_data || @html_attrs&.dig(:"x-data") || alpine_component
36
44
  if alpine_component_name.present?
37
- args = Array.wrap(alpine_data)
38
- args.any? ? "#{alpine_component_name}(#{safe_join(args)})" : alpine_component_name
45
+ args = Array.wrap(alpine_data).compact
46
+ args.any? ? "#{alpine_component_name}(#{args.join(",")})" : alpine_component_name
39
47
  end
40
48
  end
41
49
  end
@@ -13,7 +13,7 @@ module Lookbook
13
13
  protected
14
14
 
15
15
  def alpine_data
16
- content ? nil : @target.to_json
16
+ content ? nil : alpine_encode(@target)
17
17
  end
18
18
 
19
19
  def alpine_component
@@ -2,15 +2,12 @@ module Lookbook
2
2
  class DimensionsDisplay::Component < Lookbook::BaseComponent
3
3
  def initialize(target:, **html_attrs)
4
4
  @target = target
5
+ @alpine_data = alpine_encode(@target)
5
6
  super(**html_attrs)
6
7
  end
7
8
 
8
9
  protected
9
10
 
10
- def alpine_data
11
- @target.to_json
12
- end
13
-
14
11
  def alpine_component
15
12
  "dimensionsDisplayComponent"
16
13
  end
@@ -20,7 +20,7 @@ module Lookbook
20
20
  end
21
21
 
22
22
  def alpine_data
23
- [@id.to_json, "$store.pages.embeds"].join(",")
23
+ [alpine_encode(@id), "$store.pages.embeds"].join(",")
24
24
  end
25
25
 
26
26
  def alpine_component
@@ -1,7 +1,7 @@
1
1
  module Lookbook
2
2
  class Icon::Component < Lookbook::BaseComponent
3
3
  def initialize(name:, size: 4, **html_attrs)
4
- @icon_name = name.is_a?(Symbol) ? name.to_s.tr("_", "-").to_json : name
4
+ @alpine_data = name.is_a?(Symbol) ? alpine_encode(name.to_s.tr("_", "-")) : name
5
5
  @size = size || 4
6
6
  super(**html_attrs)
7
7
  end
@@ -12,10 +12,6 @@ module Lookbook
12
12
 
13
13
  protected
14
14
 
15
- def alpine_data
16
- @icon_name
17
- end
18
-
19
15
  def alpine_component
20
16
  "iconComponent"
21
17
  end
@@ -11,7 +11,7 @@
11
11
  </div>
12
12
  <% end %>
13
13
 
14
- <div class="overflow-auto">
14
+ <div class="overflow-auto h-full">
15
15
  <% if items.any? %>
16
16
  <ul class="py-2" x-ref="items" x-show="!empty" x-cloak>
17
17
  <%= safe_join(items) %>
@@ -78,10 +78,10 @@ module Lookbook
78
78
  protected
79
79
 
80
80
  def alpine_data
81
- {
81
+ alpine_encode({
82
82
  id: @item.id,
83
83
  matchers: item.is_a?(Lookbook::Collection) ? nil : item.matchers
84
- }.to_json
84
+ })
85
85
  end
86
86
 
87
87
  def alpine_component
@@ -33,7 +33,7 @@ module Lookbook
33
33
  protected
34
34
 
35
35
  def alpine_data
36
- escaped_value = helpers.raw json_escape(value.to_json)
36
+ escaped_value = json_escape(value.to_json)
37
37
  "{name: '#{name}', value: #{escaped_value}}"
38
38
  end
39
39
 
@@ -1,4 +1,4 @@
1
- import debounce from "debounce";
1
+ import { debounce } from "throttle-debounce";
2
2
  import tippy from "~/app/assets/lookbook/js/lib/tippy";
3
3
  import { observeSize } from "@helpers/layout";
4
4
  import { getElementSize } from "@helpers/dom";
@@ -49,7 +49,7 @@ export default function tabsComponent(store) {
49
49
 
50
50
  this.parentObserver = observeSize(
51
51
  this.$root.parentElement,
52
- debounce(this.handleResize.bind(this), 10)
52
+ debounce(10, this.handleResize.bind(this))
53
53
  );
54
54
 
55
55
  this.$watch("visibleTabsCount", (value) => {
@@ -1,6 +1,9 @@
1
1
  module Lookbook
2
2
  class ApplicationController < ActionController::Base
3
- content_security_policy false, if: -> { Rails.env.development? }
3
+ if respond_to?(:content_security_policy)
4
+ content_security_policy false, if: -> { Rails.env.development? }
5
+ end
6
+
4
7
  protect_from_forgery with: :exception
5
8
 
6
9
  helper Lookbook::ApplicationHelper
@@ -8,6 +11,7 @@ module Lookbook
8
11
  helper Lookbook::ComponentHelper
9
12
 
10
13
  before_action :generate_theme_overrides
14
+ before_action :assign_collections
11
15
 
12
16
  def self.controller_path
13
17
  "lookbook"
@@ -28,6 +32,11 @@ module Lookbook
28
32
  @theme_overrides ||= Lookbook.theme.to_css
29
33
  end
30
34
 
35
+ def assign_collections
36
+ @previews = Preview.all
37
+ @pages = Page.all
38
+ end
39
+
31
40
  def feature_enabled?(feature)
32
41
  Lookbook::Features.enabled?(feature)
33
42
  end
@@ -18,7 +18,6 @@ module Lookbook
18
18
  end
19
19
 
20
20
  def show
21
- @pages = Lookbook.pages
22
21
  @page = @pages.find_by_path(params[:path])
23
22
  if @page
24
23
  @next_page = @pages.find_next(@page)
@@ -158,22 +158,25 @@ module Lookbook
158
158
 
159
159
  def panels
160
160
  return @panels if @panels.present?
161
- @panels = []
162
- Lookbook.config.inspector_panels.each do |name, config|
161
+ inspector_data_hash = inspector_data.to_h
162
+ panel_counts = {}
163
+
164
+ @panels = Lookbook.config.inspector_panels.map do |name, config|
163
165
  config_with_defaults = Lookbook.config.inspector_panel_defaults.merge(config)
166
+ panel_counts[config_with_defaults[:pane].to_sym] ||= 0
167
+ panel_counts[config_with_defaults[:pane].to_sym] += 1
164
168
 
165
169
  callable_data = {
166
170
  name: name.to_s,
167
- index_position: (@panels.count { |p| p.pane == config.pane } + 1),
168
- **inspector_data
171
+ index_position: panel_counts[config_with_defaults[:pane].to_sym],
172
+ **inspector_data_hash
169
173
  }
170
174
 
171
175
  resolved_config = config_with_defaults.transform_values do |value|
172
176
  value.instance_of?(Proc) ? value.call(Lookbook::Store.new(callable_data)) : value
173
177
  end
174
178
  resolved_config[:name] = name.to_s
175
-
176
- @panels << Lookbook::Store.new(resolved_config, deep: false)
179
+ Store.new(resolved_config)
177
180
  end
178
181
 
179
182
  @panels = @panels.select(&:show).sort_by { |p| [p.position, p.label] }
@@ -6,7 +6,8 @@ module Lookbook
6
6
  render Lookbook::Icon::Component.new(name: name, **attrs)
7
7
  end
8
8
 
9
- def code(**attrs, &block)
9
+ def code(language = :html, **attrs, &block)
10
+ attrs[:language] ||= language
10
11
  render Lookbook::Code::Component.new(**attrs), &block
11
12
  end
12
13
 
@@ -1,5 +1,5 @@
1
1
  <% content_for :shell do %>
2
- <% if Lookbook.previews? || Lookbook.pages? %>
2
+ <% if @previews.any? || @pages.any? %>
3
3
  <%= render_component :split_layout,
4
4
  alpine_data: "$store.layout.main",
5
5
  ":class": "$store.layout.mobile && '!block'" do |layout| %>
@@ -14,14 +14,14 @@
14
14
  cloak: true do %>
15
15
 
16
16
  <%= render_component :split_layout,
17
- alpine_data: "$store.layout.#{Lookbook.pages? && Lookbook.previews? ? "sidebar" : "singleSectionSidebar"}",
17
+ alpine_data: "$store.layout.#{@pages.any? && @previews.any? ? "sidebar" : "singleSectionSidebar"}",
18
18
  style: "height: calc(100vh - 2.5rem);" do |layout| %>
19
19
 
20
- <% if Lookbook.previews? %>
20
+ <% if @previews.any? %>
21
21
  <% layout.pane class: "overflow-hidden" do %>
22
22
  <%= render_component :nav,
23
23
  id: "previews-nav",
24
- collection: Lookbook.previews,
24
+ collection: @previews,
25
25
  alpine_data: "$store.nav.previews",
26
26
  collapse_singles: true do |nav| %>
27
27
  <%= nav.toolbar do |toolbar| %>
@@ -34,11 +34,11 @@
34
34
  <% end %>
35
35
  <% end %>
36
36
 
37
- <% if Lookbook.pages? %>
37
+ <% if @pages.any? %>
38
38
  <% layout.pane class: "overflow-hidden" do %>
39
39
  <%= render_component :nav,
40
40
  id: "pages-nav",
41
- collection: Lookbook.pages,
41
+ collection: @pages,
42
42
  alpine_data: "$store.nav.pages" do |nav| %>
43
43
  <%= nav.toolbar do |toolbar| %>
44
44
  <% toolbar.section padded: true do %>
@@ -49,36 +49,6 @@
49
49
  <% end %>
50
50
  <% end %>
51
51
  <% end %>
52
-
53
- <% if Lookbook::Preview.errors.any? %>
54
- <div x-data="{hidden: false}" class="flex-none border-t border-lookbook-divider absolute bottom-0 left-0 right-0" x-show="!hidden">
55
- <%= render_component :toolbar do |toolbar| %>
56
- <% toolbar.section padded: true, class: "flex items-center" do %>
57
- <%= icon :alert_triangle, size: 4, class: "text-red-700" %>
58
- <span class="ml-2">Preview load errors</span>
59
- <% end %>
60
- <% toolbar.section align: :right do %>
61
- <% render_component :button, icon: :x, "@click": "hidden = !hidden" %>
62
- <% end %>
63
- <% end %>
64
-
65
- <div class="h-full max-h-[300px] overflow-hidden">
66
- <div class="bg-red-50 w-full overflow-auto h-full">
67
- <ul class="text-sm divide-y divide-red-200">
68
- <% Lookbook::Preview.errors.each do |error| %>
69
- <% error = error.is_a?(Lookbook::Error) ? error : Lookbook::Error.new(error) %>
70
- <li class="px-4 py-3">
71
- <h4 class="break-all leading-tight text-xs ">
72
- <%= error.file_name %><%= ":#{error.line_number}" if error.line_number %>
73
- </h4>
74
- <pre class="text-red-800 text-xs mt-2 whitespace-pre-wrap opacity-80 font-mono"><%= error.message %></pre>
75
- </li>
76
- <% end %>
77
- </ul>
78
- </div>
79
- </div>
80
- </div>
81
- <% end %>
82
52
  <% end %>
83
53
 
84
54
  <% layout.pane id: "app-main", class: "overflow-hidden h-full", ":class": "$store.layout.mobile && 'w-screen'" do %>
@@ -1,10 +1,10 @@
1
1
  <div id="landing" class="flex flex-col items-center justify-center h-full w-full">
2
- <div class="text-center" id="landing-<%= Lookbook.previews? ? "with" : "no" %>-content">
2
+ <div class="text-center" id="landing-<%= @previews.any? ? "with" : "no" %>-content">
3
3
  <h5 class="text-base text-lookbook-blank-slate-title truncate uppercase font-black tracking-wider mb-2">
4
4
  <%= config.project_name %>
5
5
  </h5>
6
6
  <div class="opacity-60">
7
- <% if Lookbook.previews? %>
7
+ <% if @previews.any? %>
8
8
  <p>Select a preview from the nav to get started.</p>
9
9
  <% else %>
10
10
  <p><a class="underline" href="https://lookbook.build/guide/previews" target="_blank">Create a preview</a> to get started.</p>
@@ -25,7 +25,7 @@
25
25
 
26
26
  <% toolbar.section divide: :left, class: "flex-none relative z-10" do %>
27
27
  <%= render_component :button_group do |group| %>
28
- <% if Lookbook.pages.any? %>
28
+ <% if @pages.any? %>
29
29
  <% group.button icon: :code,
30
30
  tooltip: "Copy page embed code",
31
31
  copy: true do %>
data/config/routes.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  Lookbook::Engine.routes.draw do
2
2
  if Lookbook::Engine.websocket?
3
- mount Lookbook::Engine.websocket => Lookbook.config.cable_mount_path
3
+ mount Lookbook::Engine.websocket => Lookbook.config.cable_mount_path, :as => :cable
4
4
  end
5
5
 
6
6
  root to: "application#index", as: :lookbook_home
@@ -5,7 +5,7 @@ require "lookbook/store"
5
5
  module Lookbook
6
6
  class Config
7
7
  def initialize
8
- @options = Store.new
8
+ @options = Store.new({}, true)
9
9
 
10
10
  @options.set({
11
11
  project_name: "Lookbook",
@@ -24,6 +24,7 @@ module Lookbook
24
24
  preview_display_params: {},
25
25
  preview_srcdoc: nil,
26
26
  preview_tags: {},
27
+ preview_disable_action_view_annotations: true,
27
28
  sort_examples: false,
28
29
 
29
30
  listen: Rails.env.development?,
@@ -31,10 +32,9 @@ module Lookbook
31
32
  listen_extensions: ["rb", "html.*"],
32
33
  listen_use_polling: false,
33
34
 
34
- cable_mount_path: "/lookbook-cable",
35
+ cable_mount_path: "/cable",
35
36
  cable_logger: Lookbook.logger,
36
37
 
37
- runtime_parsing: !Rails.env.production?,
38
38
  parser_registry_path: "tmp/storage/.yardoc",
39
39
 
40
40
  ui_theme: "indigo",
@@ -104,6 +104,10 @@ module Lookbook
104
104
  })
105
105
  end
106
106
 
107
+ def runtime_parsing=(value)
108
+ Lookbook.logger.warn "The `runtime_parsing` config option has been deprecated and will be removed in v2.0"
109
+ end
110
+
107
111
  def project_name
108
112
  @options.project_name == false ? nil : @options.project_name
109
113
  end
data/lib/lookbook/data.rb CHANGED
@@ -1,11 +1,11 @@
1
1
  module Lookbook
2
2
  module Data
3
3
  def data
4
- @data ||= Store.new
4
+ @data ||= Store.new({}, true)
5
5
  end
6
6
 
7
7
  def data=(props)
8
- @data = Store.new(props)
8
+ @data = Store.new(props, true)
9
9
  end
10
10
  end
11
11
  end
@@ -35,7 +35,7 @@ module Lookbook
35
35
  {
36
36
  version: version,
37
37
  env: Rails.env.to_s,
38
- config: config
38
+ config: config.to_h
39
39
  }
40
40
  end
41
41
 
@@ -43,18 +43,10 @@ module Lookbook
43
43
  Preview.all
44
44
  end
45
45
 
46
- def previews?
47
- Preview.any?
48
- end
49
-
50
46
  def pages
51
47
  Page.all
52
48
  end
53
49
 
54
- def pages?
55
- Page.any?
56
- end
57
-
58
50
  def broadcast(event_name, data = {})
59
51
  Engine.websocket&.broadcast(event_name.to_s, data)
60
52
  end
@@ -99,6 +91,11 @@ module Lookbook
99
91
  @preview_controller = Lookbook.config.preview_controller.constantize
100
92
  @preview_controller.include(Lookbook::PreviewController)
101
93
 
94
+ parser.after_parse do |registry|
95
+ Preview.load!(registry.all(:class))
96
+ reload_ui
97
+ end
98
+
102
99
  if Gem::Version.new(Rails.version) >= Gem::Version.new("6.1.3.1")
103
100
  # Rails.application.server is only available for newer Rails versions
104
101
  Rails.application.server do
@@ -111,19 +108,9 @@ module Lookbook
111
108
  end
112
109
  end
113
110
 
114
- if config.lookbook.runtime_parsing
115
- Lookbook::Engine.parser.parse
116
- else
117
- unless File.exist?(config.lookbook.parser_registry_path)
118
- Lookbook.logger.warn "
119
- Runtime parsing is disabled but no registry file has been found.
120
- Did you run `rake lookbook:preparse` before starting the app?
121
- Expected to find registry file at #{config.lookbook.parser_registry_path}
122
- "
123
- end
111
+ parser.parse do
112
+ Lookbook::Engine.run_hooks(:after_initialize)
124
113
  end
125
-
126
- Lookbook::Engine.run_hooks(:after_initialize)
127
114
  end
128
115
 
129
116
  at_exit do
@@ -140,43 +127,40 @@ module Lookbook
140
127
  return unless config.listen == true
141
128
  Listen.logger = Lookbook.logger
142
129
 
143
- preview_listener = Listen.to(
144
- *config.listen_paths,
145
- only: /\.(#{config.listen_extensions.join("|")})$/,
146
- force_polling: config.listen_use_polling
147
- ) do |modified, added, removed|
148
- changes = {modified: modified, added: added, removed: removed}
149
- begin
150
- parser.parse
151
- rescue
130
+ listen_paths = config.listen_paths.uniq
131
+ if listen_paths.any?
132
+ preview_listener = Listen.to(*listen_paths,
133
+ only: /\.(#{config.listen_extensions.join("|")})$/,
134
+ force_polling: config.listen_use_polling) do |modified, added, removed|
135
+ parser.parse do
136
+ run_hooks(:after_change, {modified: modified, added: added, removed: removed})
137
+ end
152
138
  end
153
- Lookbook::Preview.clear_cache
154
- reload_ui(changes)
155
- run_hooks(:after_change, changes)
139
+ register_listener(preview_listener)
156
140
  end
157
- register_listener(preview_listener)
158
-
159
- page_listener = Listen.to(
160
- *config.page_paths,
161
- only: /\.(html.*|md.*)$/,
162
- force_polling: config.listen_use_polling
163
- ) do |modified, added, removed|
164
- changes = {modified: modified, added: added, removed: removed}
165
- reload_ui(changes)
166
- run_hooks(:after_change, changes)
141
+
142
+ page_paths = config.page_paths.uniq
143
+ if page_paths.any?
144
+ page_listener = Listen.to(*page_paths,
145
+ only: /\.(html.*|md.*)$/,
146
+ force_polling: config.listen_use_polling) do |modified, added, removed|
147
+ changes = {modified: modified, added: added, removed: removed}
148
+ reload_ui
149
+ run_hooks(:after_change, changes)
150
+ end
151
+ register_listener(page_listener)
167
152
  end
168
- register_listener(page_listener)
169
153
  end
170
154
 
171
155
  def websocket
172
156
  config = Lookbook.config
173
157
  return @websocket unless @websocket.nil?
174
- return unless config.auto_refresh == true
158
+ return unless config.auto_refresh == true && config.listen == true && !Rails.env.test?
175
159
  Lookbook.logger.info "Initializing websocket"
176
160
 
177
161
  cable = ActionCable::Server::Configuration.new
178
162
  cable.cable = {adapter: "async"}.with_indifferent_access
179
- cable.mount_path = config.cable_mount_path
163
+ cable.mount_path = nil
180
164
  cable.connection_class = -> { Lookbook::Connection }
181
165
  cable.logger = config.cable_logger
182
166
 
@@ -190,7 +174,7 @@ module Lookbook
190
174
  end
191
175
 
192
176
  def websocket_mount_path
193
- "#{mounted_path}#{config.lookbook.cable_mount_path}" if websocket?
177
+ "#{mounted_path}#{config.lookbook.cable_mount_path}".gsub("//", "/") if websocket?
194
178
  end
195
179
 
196
180
  def websocket?
@@ -202,7 +186,7 @@ module Lookbook
202
186
  end
203
187
 
204
188
  def parser
205
- @parser ||= Lookbook::Parser.new(config.lookbook.preview_paths, config.lookbook.parser_registry_path)
189
+ @parser ||= Lookbook::Parser.new(config.lookbook.preview_paths)
206
190
  end
207
191
 
208
192
  def log_level
@@ -237,8 +221,8 @@ module Lookbook
237
221
  end
238
222
  end
239
223
 
240
- def reload_ui(changed = {})
241
- websocket&.broadcast("reload", changed)
224
+ def reload_ui
225
+ websocket&.broadcast("reload", {})
242
226
  end
243
227
 
244
228
  def prevent_listening?
@@ -3,24 +3,32 @@ require "yard"
3
3
  module Lookbook
4
4
  class Parser
5
5
  attr_reader :registry_path
6
- def initialize(paths, registry_path)
6
+ def initialize(paths)
7
7
  @paths = paths.map { |p| "#{p}/**/*preview.rb" }
8
- @registry_path = registry_path.to_s
9
- YARD::Registry.yardoc_file = registry_path
8
+ @after_parse_callbacks = []
9
+ @after_parse_once_callbacks = []
10
+ @parsing = false
11
+
12
+ YARD::Parser::SourceParser.after_parse_list do
13
+ [*@after_parse_callbacks, *@after_parse_once_callbacks].each do |callback|
14
+ callback.call(YARD::Registry)
15
+ end
16
+ @after_parse_once_callbacks = []
17
+ @parsing = false
18
+ end
10
19
  end
11
20
 
12
- def parse
13
- YARD::Registry.clear
14
- YARD::Registry.lock_for_writing do
21
+ def parse(&block)
22
+ unless @parsing
23
+ @parsing = true
24
+ @after_parse_once_callbacks << block if block
25
+ YARD::Registry.clear
15
26
  YARD.parse(@paths)
16
- YARD::Registry.save(false, registry_path)
17
27
  end
18
28
  end
19
29
 
20
- def get_code_object(path)
21
- registry = YARD::RegistryStore.new
22
- registry.load!(registry_path)
23
- registry.get(path)
30
+ def after_parse(&block)
31
+ @after_parse_callbacks << block
24
32
  end
25
33
 
26
34
  class << self