Skip to content

More HotWired improvements & Websockets #1454

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 36 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
dd73c34
initial work on Seaside-WebSocket, inspired by Seaside-Comet
Aug 16, 2022
a8dc18e
added websocket packages to the baseline
Aug 16, 2022
c2aa27a
fix websockets in baseline
Aug 16, 2022
701487a
Move class ZnSeasideWebSocketDelegate to Seaside-WebSocket-Zinc package
Aug 16, 2022
c5ebab2
Created a dedicated request handler for websocket setup + some change…
Aug 16, 2022
0217078
pushing javascript for execution moved to separate subclass of websoc…
Aug 16, 2022
1611ec2
Some improvements to the code as per PR feedback
Aug 22, 2022
6307cfc
Added the slider example using websockets
Aug 22, 2022
64c3a5b
send/receive over websocket touches session preventing expiry
Dec 27, 2022
9efdaf3
Merge branch 'master' into websockets
Dec 27, 2022
e34adad
Merge branch 'master' into websockets
Jul 14, 2024
f305106
Correct baseline for websockets
Jul 14, 2024
944f3e1
just some code style corrections
Jul 23, 2024
abe043f
Expanded basic tests for Hotwired and added turboShow: onAnswer:
Feb 24, 2025
92c4284
Merge branch 'master' into hotwired-tests
Mar 28, 2025
878ea91
Merge branch 'master' into hotwired-tests
Apr 15, 2025
6e40b22
update to turbo 8.0.13
Jun 10, 2025
51b9e3b
Added lazy-loaded turboframes and expanded functional tests
Jun 13, 2025
0f5c233
Merge branch 'master' into websockets
Jun 13, 2025
8d246ac
Merge branch 'websockets' into hotwired-tests
Jun 13, 2025
ed0e200
fix test
Jun 13, 2025
cbe580d
Hotwire turbo over websockets: primary version
Jun 18, 2025
2f75eb3
Code improvements for websockets
Jun 18, 2025
3925a04
Moved some websocket methods to the core as the websocket code cannot…
Jun 19, 2025
2a6f4ae
mark websockets unsupported in gemstone (for now)
Jun 19, 2025
d467682
repackage websockets...
Jun 19, 2025
1fe17d7
added more Turbo options
Jun 19, 2025
692825a
Added some basic Stimulus support
Jun 20, 2025
2efdf89
Pharo 13 is standard in the tests now; set experimental to Pharo 14
Jun 23, 2025
345c720
increment version number
Jun 23, 2025
c6b8270
Merge 2efdf89333e6e313133e63e38c80cdb1f1aba0d7
Jun 23, 2025
79b9da6
test fix
Jun 23, 2025
b5d2d15
dataAttributeAt:put: returns the value of at:put: for consistency wit…
Jun 25, 2025
0822855
Add morphing option to turbostream builder actions
Jun 25, 2025
d30ba56
Websocket pusher for turbostream
Jun 25, 2025
20cb5cc
Class browser example with Hotwire turbo and websocket
Jun 26, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ jobs:
strategy:
fail-fast: false
matrix:
smalltalk: [ Pharo64-12, Pharo64-11, Pharo64-10, Pharo64-9.0, Pharo64-8.0, GemStone64-3.7.1, GemStone64-3.6.8, GemStone64-3.5.8 ]
smalltalk: [ Pharo64-13, Pharo64-12, Pharo64-11, Pharo64-10, Pharo64-9.0, Pharo64-8.0, GemStone64-3.7.1, GemStone64-3.6.8, GemStone64-3.5.8 ]
experimental: [ false ]
include:
- smalltalk: Pharo64-13
- smalltalk: Pharo64-14
experimental: true
- smalltalk: GToolkit64-release
experimental: true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ baseline: spec
self baselinefilesystem: spec.
self baselineadaptors: spec.
self baselinecomet: spec.
self baselinewebsocket: spec.
self baselinejavascript: spec.
self baselinejquery: spec.
self baselinejqueryui: spec.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,15 @@ baselineadaptors: spec

spec
for: #pharo
do: [
do: [
spec
baseline: 'Zinc WebSockets'
with: [
spec
className: 'BaselineOfZincHTTPComponents';
loads: #('WebSocket');
repository: 'github://svenvc/zinc:master/repository' ].

spec
package: 'Seaside-Adaptors-Comanche' with: [ spec requires: #('KomHttpServerLight' 'Seaside-Core') ];
package: 'KomHttpServerLight' with: [ spec repository: 'http://www.smalltalkhub.com/mc/Seaside/KomHttpServer/main' ];
Expand All @@ -56,7 +64,8 @@ baselineadaptors: spec

spec
for: #gemstone
do: [ spec
do: [
spec
project: 'FastCGI Project'
with: [ spec
className: 'ConfigurationOfGsFastCGI';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ baselinecommon: spec
spec requires: #('Seaside-Component' 'Seaside-Canvas' ) ];
package: 'Seaside-HotwireTurbo-Core' with: [
spec requires: #('Seaside-Core' 'Seaside-Component' 'Seaside-Canvas' 'Seaside-RenderLoop' ) ];
package: 'Seaside-HotwireStimulus-Core' with: [
spec requires: #('Seaside-Core' 'Seaside-Component' 'Seaside-Canvas' 'Seaside-RenderLoop' ) ];
package: 'Seaside-HotwireTurbo-Examples' with: [
spec requires: #('Seaside-HotwireTurbo-Core' 'Seaside-Examples') ];
package: 'Seaside-Tests-Canvas' with: [
Expand Down Expand Up @@ -112,7 +114,7 @@ baselinecommon: spec

group: 'Core' with: #('Seaside-Core' 'Seaside-Continuation' 'Seaside-Canvas' 'Seaside-Session' 'Seaside-Component' 'Seaside-RenderLoop' 'Seaside-Tools-Core' 'Seaside-Flow' 'Seaside-Environment' 'Seaside-Widgets' );
group: 'Tests' with: #('Core' 'Seaside-Tests-Core' 'Seaside-Tests-Canvas' 'Seaside-Tests-Session' 'Seaside-Tests-Component' 'Seaside-Tests-RenderLoop' 'Seaside-Tests-Environment' 'Seaside-Tests-Flow' 'Seaside-Tests-UTF8' 'Seaside-Tests-InternetExplorer' 'Seaside-Tests-Email' 'Seaside-Tests-Examples' 'Seaside-Tests-WebComponents' 'RSS Tests' 'Welcome Tests' 'REST Tests' 'Swagger Tests' 'Seaside-Tests-Parasol' 'Seaside-Tests-HotwireTurbo');
group: 'Hotwired' with: #('Seaside-HotwireTurbo-Core');
group: 'Hotwired' with: #('Seaside-HotwireTurbo-Core' 'Seaside-HotwireStimulus-Core');
group: 'Development' with: #('Core' 'Seaside-Development');
group: 'Development Tests' with: #('Development' 'Core' 'Seaside-Tests-Development');
group: 'Email' with: #('Seaside-Email');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ baselinegettext: spec
with: [ spec requires: #('Seaside-Gettext-Examples') ].
spec
group: 'Seaside-Gettext' with: #('Seaside-Gettext-Core');
group: 'Gettext-Examples'
with: #('Seaside-Gettext' 'Seaside-Gettext-Examples');
group: 'Gettext-Examples' with: #('Seaside-Gettext' 'Seaside-Gettext-Examples');
group: 'Tests' with: #('Seaside-Tests-Gettext-Core' 'Gettext-Examples') ].

spec
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
baselines
baselinewebsocket: spec

spec for: #'pharo' do: [
spec blessing: #baseline.
spec
package: 'Seaside-WebSocket-Core' with: [
spec requires: #('Javascript-Core' 'Seaside-Canvas' ) ];
" package: 'Seaside-WebSocket-Tests-Core' with: [
spec requires: #('Javascript-Tests-Core' 'Seaside-WebSocket-Core' ) ];"
package: 'Seaside-WebSocket-Zinc' with:[
spec requires: #('Zinc' 'Zinc WebSockets') ];
package: 'Seaside-WebSocket-Examples' with: [
spec requires: #('JQuery-Core' 'Seaside-WebSocket-Core') ].

spec
group: 'WebSocket' with: #('Seaside-WebSocket-Core' 'Seaside-WebSocket-Zinc');
" group: 'WebSocket Tests' with: #('Seaside-WebSocket-Tests-Core' );"
group: 'Examples' with: #('Seaside-WebSocket-Examples' )
"group: 'Tests' with: #('WebSocket Tests')" ]
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
accessing-attributes
attributeAt: aKey put: aValue if: aBoolean

^ aBoolean ifTrue:[ self attributes at: aKey put: aValue ]

Check warning on line 4 in repository/Seaside-Canvas.package/WATagBrush.class/instance/attributeAt.put.if..st

View check run for this annotation

Codecov / codecov/patch

repository/Seaside-Canvas.package/WATagBrush.class/instance/attributeAt.put.if..st#L1-L4

Added lines #L1 - L4 were not covered by tests
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
attributes
dataAttributeAt: aString put: aValue

self attributeAt: 'data-',aString put: aValue
^ self attributeAt: 'data-',aString put: aValue
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
attributes
dataAttributeAt: aString put: aValue if: aBoolean

aBoolean ifTrue:[ self dataAttributeAt: aString put: aValue ]
^ aBoolean ifTrue:[ self dataAttributeAt: aString put: aValue ]
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
seasideVersion
"Answer the Seaside version"

^ (GRVersion major: 3 minor: 5 revision: 9)
^ (GRVersion major: 3 minor: 6 revision: 0)
yourself
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
testing
isWebSocketSetupRequest
"Return true when request can be considered a valid WebSocket setup request"

^ self isGet
and: [ (self headerAt: 'upgrade' ifAbsent: [ ^ false ]) asLowercase = 'websocket'
and: [ (self headerAt: 'connection' ifAbsent: [ ^ false ]) asLowercase = 'upgrade'
and: [ (self headerAt: 'sec-websocket-version' ifAbsent: [ ^ false ]) = '13'
and: [ self headers includesKey: 'sec-websocket-key' ] ] ] ]
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
accessing
webSocket
^ self properties at: #webSocket ifAbsent:[ nil ]

Check warning on line 3 in repository/Seaside-Core.package/WARequestContext.class/instance/webSocket.st

View check run for this annotation

Codecov / codecov/patch

repository/Seaside-Core.package/WARequestContext.class/instance/webSocket.st#L1-L3

Added lines #L1 - L3 were not covered by tests
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
handling
handleFiltered: aRequestContext
"Handle aRequestContext by either dispatching to a different request handler of by producing a response and singalling the result."
"Handle aRequestContext by either dispatching to a different request handler of by producing a response and signalling the result."

self subclassResponsibility
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
as yet unclassified
websocketSetupResponseFrom: aRequestContext

Error signal: 'Web sockets not supported yet in GemStone'
5 changes: 5 additions & 0 deletions repository/Seaside-HotwireStimulus-Core.package/.filetree
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"separateMethodMetaAndSource" : false,
"noMethodMetaData" : true,
"useCypressPropertiesFile" : true
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*Seaside-HotwireStimulus-Core
stimulusAction: aString

self dataAttributeAt: 'action' put: aString

Check warning on line 4 in repository/Seaside-HotwireStimulus-Core.package/WATagBrush.extension/instance/stimulusAction..st

View check run for this annotation

Codecov / codecov/patch

repository/Seaside-HotwireStimulus-Core.package/WATagBrush.extension/instance/stimulusAction..st#L1-L4

Added lines #L1 - L4 were not covered by tests
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*Seaside-HotwireStimulus-Core
stimulusController: aString

self dataAttributeAt: 'controller' put: aString

Check warning on line 4 in repository/Seaside-HotwireStimulus-Core.package/WATagBrush.extension/instance/stimulusController..st

View check run for this annotation

Codecov / codecov/patch

repository/Seaside-HotwireStimulus-Core.package/WATagBrush.extension/instance/stimulusController..st#L1-L4

Added lines #L1 - L4 were not covered by tests
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*Seaside-HotwireStimulus-Core
stimulusTarget: targetName inController: controllerName

self dataAttributeAt: controllerName,'-target' put: targetName

Check warning on line 4 in repository/Seaside-HotwireStimulus-Core.package/WATagBrush.extension/instance/stimulusTarget.inController..st

View check run for this annotation

Codecov / codecov/patch

repository/Seaside-HotwireStimulus-Core.package/WATagBrush.extension/instance/stimulusTarget.inController..st#L1-L4

Added lines #L1 - L4 were not covered by tests
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name" : "WATagBrush"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
self packageOrganizer ensurePackage: #'Seaside-HotwireStimulus-Core' withTags: #()!
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
(name 'Seaside-HotwireStimulus-Core')
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ }
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
*Seaside-HotwireTurbo-Core
turboConfirm: aString
"Decorate links with both data-turbo-confirm and data-turbo-method,
and confirmation will be required for a visit to proceed.
https://turbo.hotwired.dev/handbook/drive#requiring-confirmation-for-a-visit"

self turboMethod: 'get'.
self dataAttributeAt: 'turbo-confirm' put: aString

Check warning on line 8 in repository/Seaside-HotwireTurbo-Core.package/WAAnchorTag.extension/instance/turboConfirm..st

View check run for this annotation

Codecov / codecov/patch

repository/Seaside-HotwireTurbo-Core.package/WAAnchorTag.extension/instance/turboConfirm..st#L1-L8

Added lines #L1 - L8 were not covered by tests
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*Seaside-HotwireTurbo-Core
turboMethod: aString

self dataAttributeAt: 'turbo-method' put: aString

Check warning on line 4 in repository/Seaside-HotwireTurbo-Core.package/WAAnchorTag.extension/instance/turboMethod..st

View check run for this annotation

Codecov / codecov/patch

repository/Seaside-HotwireTurbo-Core.package/WAAnchorTag.extension/instance/turboMethod..st#L1-L4

Added lines #L1 - L4 were not covered by tests
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*Seaside-HotwireTurbo-Core
renderLazyTurboFrameContentsOn: html
"Subclasses can override this to render the placeholder contents for a lazy-loaded turboframe decoration of themselves."
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
*Seaside-HotwireTurbo-Core
turboShow: aComponent

aComponent addDecoration: (WATurboFrame newWithId: self turboframeDecoration id).
^ self show: aComponent
^ self turboShow: aComponent onAnswer: [ :value | ]
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
*Seaside-HotwireTurbo-Core
turboShow: aComponent onAnswer: aBlock

aComponent addDecoration: (WATurboFrame newWithId: self turboframeDecoration id).
^ self show: aComponent onAnswer: aBlock

Check warning on line 5 in repository/Seaside-HotwireTurbo-Core.package/WAComponent.extension/instance/turboShow.onAnswer..st

View check run for this annotation

Codecov / codecov/patch

repository/Seaside-HotwireTurbo-Core.package/WAComponent.extension/instance/turboShow.onAnswer..st#L1-L5

Added lines #L1 - L5 were not covered by tests
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*Seaside-HotwireTurbo-Core
renderLazyTurboFrameContentsOn: html

self next renderLazyTurboFrameContentsOn: html

Check warning on line 4 in repository/Seaside-HotwireTurbo-Core.package/WADecoration.extension/instance/renderLazyTurboFrameContentsOn..st

View check run for this annotation

Codecov / codecov/patch

repository/Seaside-HotwireTurbo-Core.package/WADecoration.extension/instance/renderLazyTurboFrameContentsOn..st#L1-L4

Added lines #L1 - L4 were not covered by tests
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
*Seaside-HotwireTurbo-Core
turboSubmitsWith: aString
"Specifies text to display when submitting a form. Can be used on input or button elements.
While the form is submitting the text of the element will show the value of data-turbo-submits-with.
After the submission, the original text will be restored.
Useful for giving user feedback by showing a message like “Saving…” while an operation is in progress."

self dataAttributeAt: 'turbo-submits-with' put: aString

Check warning on line 8 in repository/Seaside-HotwireTurbo-Core.package/WAFormInputTag.extension/instance/turboSubmitsWith..st

View check run for this annotation

Codecov / codecov/patch

repository/Seaside-HotwireTurbo-Core.package/WAFormInputTag.extension/instance/turboSubmitsWith..st#L1-L8

Added lines #L1 - L8 were not covered by tests
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name" : "WAFormInputTag"
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
attributes
*Seaside-HotwireTurbo-Core

Check warning on line 1 in repository/Seaside-HotwireTurbo-Core.package/WAMetaElement.extension/instance/turboPrefetch..st

View check run for this annotation

Codecov / codecov/patch

repository/Seaside-HotwireTurbo-Core.package/WAMetaElement.extension/instance/turboPrefetch..st#L1

Added line #L1 was not covered by tests
turboPrefetch: aString
"Prefetching links is enabled by default since Turbo v8,
but you can disable it by adding this meta tag to your page with value false."
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
*Seaside-HotwireTurbo-Core
turboRefreshMethod: aString

"The possible values are 'morph' or 'replace' (the default).
When it is morph, when a page refresh happens, instead of replacing the page’s <body> contents,
Turbo will only update the DOM elements that have changed, keeping the rest untouched.
This approach delivers better sensations because it keeps the screen state.
https://turbo.hotwired.dev/handbook/page_refreshes.html"

self name: 'turbo-refresh-method'.
self content: aString

Check warning on line 11 in repository/Seaside-HotwireTurbo-Core.package/WAMetaElement.extension/instance/turboRefreshMethod..st

View check run for this annotation

Codecov / codecov/patch

repository/Seaside-HotwireTurbo-Core.package/WAMetaElement.extension/instance/turboRefreshMethod..st#L1-L11

Added lines #L1 - L11 were not covered by tests
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
*Seaside-HotwireTurbo-Core
turboRefreshScroll: aString

"The possible values are 'preserve' or 'reset' (the default).
When it is preserve, when a page refresh happens, Turbo will keep the page’s vertical and horizontal scroll.
https://turbo.hotwired.dev/handbook/page_refreshes.html#scroll-preservation"

self name: 'turbo-refresh-scroll'.
self content: aString

Check warning on line 9 in repository/Seaside-HotwireTurbo-Core.package/WAMetaElement.extension/instance/turboRefreshScroll..st

View check run for this annotation

Codecov / codecov/patch

repository/Seaside-HotwireTurbo-Core.package/WAMetaElement.extension/instance/turboRefreshScroll..st#L1-L9

Added lines #L1 - L9 were not covered by tests
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
*Seaside-HotwireTurbo-Core
turboRoot: aString
"Include a <meta name=""turbo-root""> element in your pages’ <head> to scope Turbo Drive to a particular root location.
Turbo Drive will only load same-origin URLs that are prefixed with this path.
https://turbo.hotwired.dev/handbook/drive#setting-a-root-location"

self name: 'turbo-root'.
self content: aString

Check warning on line 8 in repository/Seaside-HotwireTurbo-Core.package/WAMetaElement.extension/instance/turboRoot..st

View check run for this annotation

Codecov / codecov/patch

repository/Seaside-HotwireTurbo-Core.package/WAMetaElement.extension/instance/turboRoot..st#L1-L8

Added lines #L1 - L8 were not covered by tests
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
*Seaside-HotwireTurbo-Core
turboVisitControl: aString
"Using the value 'reload' will perform a full page reload whenever Turbo navigates to the page,
including when the request originates from a <turbo-frame>"

self name: 'turbo-visit-control'.
self content: aString

Check warning on line 7 in repository/Seaside-HotwireTurbo-Core.package/WAMetaElement.extension/instance/turboVisitControl..st

View check run for this annotation

Codecov / codecov/patch

repository/Seaside-HotwireTurbo-Core.package/WAMetaElement.extension/instance/turboVisitControl..st#L1-L7

Added lines #L1 - L7 were not covered by tests
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name" : "WAMetaElement"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
*Seaside-HotwireTurbo-Core
turboEval: aString
"Annotate <script> elements with data-turbo-eval=""false"" if you do not want
Turbo to evaluate them after rendering.
Note that this annotation will not prevent your browser from evaluating scripts on the initial page load."

self dataAttributeAt: 'turbo-eval' put: aString

Check warning on line 7 in repository/Seaside-HotwireTurbo-Core.package/WAScriptTag.extension/instance/turboEval..st

View check run for this annotation

Codecov / codecov/patch

repository/Seaside-HotwireTurbo-Core.package/WAScriptTag.extension/instance/turboEval..st#L1-L7

Added lines #L1 - L7 were not covered by tests
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name" : "WAScriptTag"
}
Loading
Loading