@csedl/svelte-on-rails 10.0.4 → 10.1.1

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.
package/README.md CHANGED
@@ -1,17 +1,5 @@
1
1
  # @csedl/svelte-on-rails
2
2
 
3
- Works together with the [svelte-on-rails](https://svelte-on-rails.dev) gem.
4
-
5
- Versions here do not have many updates here, and are more dependend on the versions from the gem.
6
- So, i added no releases here.
7
- Checkout Release Notes on the gems repository.
8
-
9
- ## Prerequisites
10
-
11
- - Please follow the [gem](https://svelte-on-rails.dev) instructions.
12
- - Svelte >= 5
13
- - tested with ruby 3.2.2 and rails 7.1
14
-
15
3
  ## Installation
16
4
 
17
5
  ```
@@ -24,32 +12,14 @@ Add to your entrypoint file, like `application.js`
24
12
  import '@csedl/svelte-on-rails';
25
13
  ```
26
14
 
27
- For configs you can do
28
-
29
- ```javascript
30
- import { SvelteOnRails } from '@csedl/svelte-on-rails'
31
- SvelteOnRails.debug = true
32
-
33
- // source for svelte components for hydration
34
- // by default svelte components are mapped by sourceCodeDir from vite.json
35
- // which usually is app/frontend/**/*.svelte
36
- SvelteOnRails.includeRailsViews = true
37
- // when set to true, additionaly, app/views/**/*.svelte is mapped
38
- // => this is a 2016 new introduced feature, status: experimental
39
- ```
40
-
41
- The `SvelteOnRails` Object is accessible by `window.SvelteOnRails`
42
-
43
- ## What it contains or does
15
+ ## What it does
44
16
 
45
17
  - It includes a stimulus controller that handles the initializing event of the svelte component,
46
18
  rendered by the ruby gem. Initializing means that the component is mounted or hydrated, together
47
19
  with the properties given by the ruby gem.
48
- - After disappearing, the component is unmounted by the disconnect event of stimulus.
49
20
 
50
- **Turbo-Streams**
21
+ ## Description
51
22
 
52
- - For working with `Turbo Streams` it contains a stimulus controller that dispatches actions
53
- on Svelte Components.
54
- - Helper for adding eventListeners on Svelte Components.
23
+ Please follow [svelte-on-rails docs](https://svelte-on-rails.dev) for more information.
55
24
 
25
+ The repository is shared with the gem [svelte-on-rails](https://gitlab.com/sedl/svelte-on-rails) (monorepo).
package/index.js CHANGED
@@ -1,7 +1,10 @@
1
1
  import SvelteOnRails from "./src/config.js";
2
2
  import {Application} from "@hotwired/stimulus"
3
3
  import {dispatchSvelteStreamEvent} from "./src/streams/dispatch-event.js";
4
- import {actionCableDebugLog} from "./src/logger.js";
4
+ import {streamDebugLog} from "./src/logger.js";
5
+
6
+
7
+ //console.error('test-error')
5
8
 
6
9
  if (!window.Stimulus) {
7
10
  window.Stimulus = Application.start()
@@ -19,4 +22,4 @@ import turboStreamController from "./src/streams/turbo-stream-controller.js";
19
22
 
20
23
  Stimulus.register('svelte-on-rails-turbo-stream', turboStreamController)
21
24
 
22
- export { SvelteOnRails, dispatchSvelteStreamEvent, actionCableDebugLog };
25
+ export { SvelteOnRails, dispatchSvelteStreamEvent, streamDebugLog };
package/package.json CHANGED
@@ -1,24 +1,23 @@
1
1
  {
2
2
  "name": "@csedl/svelte-on-rails",
3
- "version": "10.0.4",
3
+ "version": "10.1.1",
4
4
  "description": "Hydrates Svelte components from the svelte-on-rails gem and can handle Actions received by Web Socket.",
5
5
  "main": "index.js",
6
6
  "type": "module",
7
7
  "exports": {
8
8
  ".": "./index.js",
9
9
  "./src/streams/componentStreamListener": "./src/streams/componentStreamListener.js",
10
- "./src/dispatch-event": "./src/streams/dispatch-event.js"
10
+ "./src/streams/dispatch-event.js": "./src/streams/dispatch-event.js",
11
+ "./src/logger.js": "./src/logger.js",
12
+ "./src/config.js": "./src/config.js"
11
13
  },
12
14
  "peerDependencies": {
13
15
  "@hotwired/stimulus": "^3.2.2",
14
16
  "svelte": "^5.50.0"
15
17
  },
16
- "scripts": {
17
- "test": "echo \"Error: no test specified\" && exit 1"
18
- },
19
18
  "repository": {
20
19
  "type": "git",
21
- "url": "git+https://gitlab.com/sedl/csedl-svelte-on-rails.git"
20
+ "url": "https://gitlab.com/sedl/svelte-on-rails"
22
21
  },
23
22
  "keywords": [
24
23
  "svelte",
@@ -28,7 +27,7 @@
28
27
  "author": "Christian Sedlmair",
29
28
  "license": "LICENSE.md",
30
29
  "bugs": {
31
- "url": "https://gitlab.com/sedl/csedl-svelte-on-rails/-/issues"
30
+ "url": "https://gitlab.com/sedl/svelte-on-rails/-/issues"
32
31
  },
33
32
  "homepage": "https://svelte-on-rails.dev"
34
33
  }
package/src/config.js CHANGED
@@ -1,11 +1,62 @@
1
+ import {streamDebugLog} from "./logger.js";
1
2
  // src/config.js
2
3
  let _debug = false;
3
- let _includeRailsViews = false;
4
- const _componentModules = import.meta.glob("/**/*.svelte", {eager: false, import: 'default'});
4
+
5
+ let _lazyComponents = {}
6
+ let _defaultComponents = import.meta.glob("/**/*.svelte", { eager: false, import: "default" });
5
7
 
6
8
  import {debugLog} from "./logger.js";
7
9
 
8
10
  const SvelteOnRails = {
11
+
12
+ async loadComponent(componentKey) {
13
+
14
+ // fetch loader from store
15
+
16
+ let components
17
+ if (Object.keys(_lazyComponents).length === 0) {
18
+ debugLog("lazyComponents not set: falling back to built-in «import.meta.glob(['/**/*.svelte'], {eager: false, import: 'default'})»");
19
+ components = _defaultComponents;
20
+ } else {
21
+ debugLog(`[svelte-on-rails] using given lazyComponents`);
22
+ components = _lazyComponents
23
+ }
24
+
25
+
26
+ const loader = components[componentKey];
27
+ console.log(`[svelte-on-rails:debug] loader`, loader);
28
+ if (!loader) {
29
+ throw new Error(`[svelte-on-rails] Component not found: ${componentKey} (relative to vites sourceCodeDir / frontend-folder)`);
30
+ //return;
31
+ } else {
32
+ console.log(`[svelte-on-rails] Component found: ${componentKey}`);
33
+ }
34
+
35
+ // load and validate component
36
+
37
+ let comp;
38
+ if (loader.prototype) {
39
+ console.warn(`[svelte-on-rails] Components should be lazy loaded. Did you use vite.meta.glob(..., {eager: true})?`);
40
+ comp = loader;
41
+ } else {
42
+ comp = await loader();
43
+ if (typeof comp !== 'function') {
44
+ throw new Error(`[svelte-on-rails] Component is not a function: ${componentKey}\nYou may need to use vite.meta.glob(..., {...import: "default"})`);
45
+ }
46
+ }
47
+
48
+ // finish
49
+
50
+ console.log(`[svelte-on-rails:debug] Component loaded:`, comp);
51
+ return comp;
52
+ },
53
+
54
+ set lazyComponents(value) {
55
+ console.log(`[svelte-on-rails:debug] lazyComponents set:`, value);
56
+ _lazyComponents = value;
57
+ },
58
+
59
+
9
60
  get debug() {
10
61
  return _debug;
11
62
  },
@@ -13,23 +64,6 @@ const SvelteOnRails = {
13
64
  _debug = !!value;
14
65
  debugLog(`Debug mode: ${_debug ? "enabled" : "disabled"}`);
15
66
  },
16
-
17
- // includeRailsViews
18
- get includeRailsViews() { // ← clearer, reads like a question
19
- return _includeRailsViews;
20
- },
21
- set includeRailsViews(value) {
22
- _includeRailsViews = !!value;
23
- debugLog(`Include components within app/views: ${_includeRailsViews ? "enabled" : "disabled"}`);
24
- if (_includeRailsViews) {
25
- const _viewComponents = import.meta.glob("/../../app/views/**/*.svelte", {eager: false, import: "default"});
26
- Object.assign(_componentModules, _viewComponents);
27
- debugLog(`loaded view-components: `);
28
- }
29
- },
30
- get components() {
31
- return(_componentModules);
32
- }
33
67
  };
34
68
 
35
69
  window.SvelteOnRails = SvelteOnRails;
@@ -7,19 +7,20 @@ const svelteInstances = new WeakMap();
7
7
  /**
8
8
  * Cleans up all initialized Svelte component instances.
9
9
  */
10
- export function cleanupSvelteComponent(element, debug = false) {
10
+ export function cleanupSvelteComponent(element) {
11
11
  try {
12
12
  const instance = svelteInstances.get(element);
13
13
  if (instance) {
14
14
  unmount(instance); // Destroy the Svelte component instance in Svelte 5
15
- debugLog(`Successfully unmounted Svelte component for element:`, element, debug);
15
+ debugLog(`Successfully unmounted Svelte component for element:`, element);
16
16
  element.removeAttribute('data-svelte-initialized'); // Reset initialized state
17
17
  svelteInstances.delete(element); // Remove from WeakMap
18
18
  } else {
19
- debugLog(`No Svelte instance found for element:`, element, debug);
19
+ let comps = document.getElementsByClassName('svelte-component')
20
+ debugLog(`Actual ${comps.length} components on the page. No Svelte instance found`, element);
20
21
  }
21
22
  } catch (e) {
22
- console.error(`[cleanupSvelteComponents] Error unmounting Svelte component for element:`, e);
23
+ console.error(`[svelte-on-rails:stream] Error unmounting Svelte component for element:`, e);
23
24
  // Fallback: Clear element content to prevent stale content
24
25
  element.innerHTML = '';
25
26
  }
@@ -17,20 +17,11 @@ export async function initializeSvelteComponent(element) {
17
17
  return;
18
18
  }
19
19
 
20
- debugLog(`start :${action} for ${componentKey}`);
20
+ debugLog(`start ${action} for ${componentKey}`);
21
21
 
22
22
  // load the component from lazy import
23
23
 
24
- const loader = SvelteOnRails.components[componentKey];
25
- if (!loader) {
26
- console.error(`[svelte-on-rails] Component not found: ${componentKey} (relative to vites sourceCodeDir / frontend-folder)`);
27
- return;
28
- }
29
- debugLog(`found: ${componentKey} from lazy-imported components`);
30
-
31
- const Component = await loader();
32
- debugLog(`loaded successfully: ${componentKey}`);
33
-
24
+ const Component = await SvelteOnRails.loadComponent(componentKey);
34
25
 
35
26
  // Parse props (unchanged)
36
27
  let props = {};
@@ -39,7 +30,7 @@ export async function initializeSvelteComponent(element) {
39
30
  try {
40
31
  props = JSON.parse(propsString);
41
32
  } catch (e) {
42
- console.error(`Error parsing data-props for ${componentKey}:`, e);
33
+ console.error(`[svelte-on-rails] Error parsing data-props for ${componentKey}:`, e);
43
34
  }
44
35
  }
45
36
 
@@ -8,7 +8,7 @@ export default class extends Controller {
8
8
  const stat = this.element.getAttribute('data-svelte-status');
9
9
  if (stat === 'do-not-hydrate-build-me') return;
10
10
 
11
- initializeSvelteComponent(this.element, false);
11
+ initializeSvelteComponent(this.element, false).then(r => {});
12
12
 
13
13
  }
14
14
 
package/src/logger.js CHANGED
@@ -4,16 +4,8 @@ export function debugLog(message, object, object2) {
4
4
  log( null, message, object, object2);
5
5
  }
6
6
 
7
- export function receiveTurboStreamDebugLog(message, object, object2) {
8
- log('receive-turbo-stream', message, object, object2);
9
- }
10
-
11
- export function receiveStreamEventDebugLog(message, object, object2) {
12
- log( 'receive-stream-event', message, object, object2);
13
- }
14
-
15
- export function actionCableDebugLog(message, object, object2) {
16
- log( 'action-cable', message, object, object2);
7
+ export function streamDebugLog(message, object, object2) {
8
+ log( 'stream', message, object, object2);
17
9
  }
18
10
 
19
11
  function log(namespace, message, object, object2) {
@@ -1,4 +1,3 @@
1
- ///import {receiveStreamEventDebugLog} from "./logger.js";
2
1
 
3
2
  // componentStreamListener.js (in your npm package)
4
3
  export function addComponentStreamListener(node, callback) {
@@ -7,7 +6,7 @@ export function addComponentStreamListener(node, callback) {
7
6
  const wrapper = node.closest('.svelte-component');
8
7
 
9
8
  if (!wrapper) {
10
- console.error('[svelte-on-rails:svelte-component] No wrapping element with class .svelte-component found!');
9
+ console.error('[svelte-on-rails:stream] No wrapping element with class .svelte-component found!');
11
10
  return;
12
11
  }
13
12
 
@@ -1,4 +1,4 @@
1
- import {receiveTurboStreamDebugLog} from "../logger.js";
1
+ import {streamDebugLog} from "../logger.js";
2
2
 
3
3
  export function dispatchSvelteStreamEvent(args) {
4
4
 
@@ -9,7 +9,7 @@ export function dispatchSvelteStreamEvent(args) {
9
9
  throw new Error(`[svelte-on-rails:dispatch-event] Invalid keys found: ${invalidKeys.join(', ')}. Allowed keys are: ${allowedKeys.join(', ')}.`);
10
10
  }
11
11
 
12
- receiveTurboStreamDebugLog(`parsed arguments:`, args)
12
+ streamDebugLog(`parsed arguments:`, args)
13
13
 
14
14
  const eventName = args.event || 'stream-action'
15
15
  const customEvent = new CustomEvent(eventName, {detail: args['eventDetail']})
@@ -27,12 +27,12 @@ function dispatchByComponent(args, event) {
27
27
  // find components
28
28
  let components
29
29
  if (args.component) {
30
- const componentsSelector = `[data-svelte-component="${args.component}"]`
30
+ const componentsSelector = `[data-component="${args.component}"]`
31
31
  components = document.querySelectorAll(componentsSelector)
32
- receiveTurboStreamDebugLog(`found ${components.length} components by selector «${componentsSelector}»`, components)
32
+ streamDebugLog(`found ${components.length} components by selector «${componentsSelector}»`, components)
33
33
  } else {
34
34
  components = Array.from(document.getElementsByClassName('svelte-component'))
35
- receiveTurboStreamDebugLog(`found ${components.length} components by class-name «svelte-component» (no components selector given)`, components)
35
+ streamDebugLog(`found ${components.length} components by class-name «svelte-component» (no components selector given)`, components)
36
36
  }
37
37
 
38
38
  // dispatch elements
@@ -42,14 +42,14 @@ function dispatchByComponent(args, event) {
42
42
  if (args.selector) {
43
43
  const elements = component.querySelectorAll(args.selector)
44
44
  if (elements.length === 0) {
45
- receiveTurboStreamDebugLog(`no elements found by selector «${args.selector}», within:`, component)
45
+ streamDebugLog(`no elements found by selector «${args.selector}», within:`, component)
46
46
  }
47
47
  elements.forEach(element => {
48
- receiveTurboStreamDebugLog(`dispatch event «${event.type}» on element:`, element)
48
+ streamDebugLog(`dispatch event «${event.type}» on element:`, element)
49
49
  element.dispatchEvent(event)
50
50
  })
51
51
  } else {
52
- receiveTurboStreamDebugLog(`dispatch event «${event.type}» on components wrapper:`, component)
52
+ streamDebugLog(`dispatch event «${event.type}» on components wrapper:`, component)
53
53
  component.dispatchEvent(event)
54
54
  }
55
55
 
@@ -64,12 +64,12 @@ function dispatchBySelector(args, event) {
64
64
  const elements = document.querySelectorAll(args.selector)
65
65
 
66
66
  if (elements.length === 0) {
67
- receiveTurboStreamDebugLog(`no elements found by selector «${args.selector}»`)
67
+ streamDebugLog(`no elements found by selector «${args.selector}»`)
68
68
  }
69
69
 
70
70
  elements.forEach(element => {
71
71
 
72
- receiveTurboStreamDebugLog(`dispatch event «${event.type}» on element:`, element)
72
+ streamDebugLog(`dispatch event «${event.type}» on element:`, element)
73
73
  element.dispatchEvent(event)
74
74
 
75
75
 
@@ -1,5 +1,5 @@
1
1
  import {Controller} from "@hotwired/stimulus"
2
- import {receiveTurboStreamDebugLog} from "../logger.js";
2
+ import {streamDebugLog} from "../logger.js";
3
3
  import {dispatchSvelteStreamEvent} from "./dispatch-event.js";
4
4
 
5
5
  export default class extends Controller {
@@ -7,7 +7,7 @@ export default class extends Controller {
7
7
  connect() {
8
8
 
9
9
  const argsBase64 = this.element.getAttribute('data-args')
10
- receiveTurboStreamDebugLog('turbo-stream received with base-64 encoded string:', argsBase64)
10
+ streamDebugLog('turbo-stream received with base-64 encoded string:', argsBase64)
11
11
 
12
12
  const decodedString = this.decodeBase64(argsBase64)
13
13
 
package/.idea/modules.xml DELETED
@@ -1,8 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="ProjectModuleManager">
4
- <modules>
5
- <module fileurl="file://$PROJECT_DIR$/.idea/node-module.iml" filepath="$PROJECT_DIR$/.idea/node-module.iml" />
6
- </modules>
7
- </component>
8
- </project>
@@ -1,12 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <module type="WEB_MODULE" version="4">
3
- <component name="NewModuleRootManager">
4
- <content url="file://$MODULE_DIR$">
5
- <excludeFolder url="file://$MODULE_DIR$/.tmp" />
6
- <excludeFolder url="file://$MODULE_DIR$/temp" />
7
- <excludeFolder url="file://$MODULE_DIR$/tmp" />
8
- </content>
9
- <orderEntry type="inheritedJdk" />
10
- <orderEntry type="sourceFolder" forTests="false" />
11
- </component>
12
- </module>
package/.idea/vcs.xml DELETED
@@ -1,6 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="VcsDirectoryMappings">
4
- <mapping directory="" vcs="Git" />
5
- </component>
6
- </project>