ruby_everywhere 0.1.9 → 0.1.10
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.
- checksums.yaml +4 -4
- data/bridge/README.md +77 -0
- data/bridge/package.json +14 -0
- data/config/importmap.rb +3 -0
- data/lib/everywhere/commands/install.rb +20 -16
- data/lib/everywhere/engine.rb +30 -0
- data/lib/everywhere/receipt.rb +11 -3
- data/lib/everywhere/version.rb +9 -6
- data/lib/everywhere.rb +3 -0
- metadata +6 -2
- /data/{lib/everywhere/javascript → bridge/everywhere}/bridge.js +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6e02deeb4f95a031a3a44bae0e87dbaece25f95a919ff817927e9eb5b611ffbb
|
|
4
|
+
data.tar.gz: db779e7819a864517b0a44a388c56b835eb724a2d697af653857936cab505ac1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a1567ed4df49616f1c05fe481812a62bc9f3eb64e816e4702756a0614e282027016a4e76ad62a3097fced1bde908a22fdba8ae6b6b6a46aa24cdc227bb8bf32e
|
|
7
|
+
data.tar.gz: ed2ecc0ff275c958291986eb8ea23b0e9fde277b62dcffc614c61dd84f2d6c4c626e8c93d07a8563b4755cb036f56f4a0107e00cc6c46280c6e61c551e259c1e
|
data/bridge/README.md
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# @rubyeverywhere/bridge
|
|
2
|
+
|
|
3
|
+
One API for the browser, the RubyEverywhere desktop shell, and (soon) Hotwire
|
|
4
|
+
Native mobile apps — the JavaScript half of [RubyEverywhere](https://rubyeverywhere.com).
|
|
5
|
+
|
|
6
|
+
App code writes to this surface only; platform differences live in adapters
|
|
7
|
+
inside the package. Everything degrades gracefully: the same page works in a
|
|
8
|
+
plain browser tab and gains native powers inside a RubyEverywhere app.
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
```sh
|
|
13
|
+
npm install @rubyeverywhere/bridge
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Using RubyEverywhere? You don't need npm at all: the `ruby_everywhere` gem
|
|
17
|
+
ships this exact package. Rails apps get it served and importmap-pinned by the
|
|
18
|
+
gem's engine (updates arrive with `bundle update ruby_everywhere`); Sinatra and
|
|
19
|
+
Hanami apps get it vendored to `public/bridge.js` by `every install`.
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
```js
|
|
24
|
+
import Everywhere from "@rubyeverywhere/bridge"
|
|
25
|
+
|
|
26
|
+
Everywhere.platform // "desktop" | "mobile" | "browser"
|
|
27
|
+
Everywhere.os // "macos" | "windows" | "linux" | "ios" | "android" | "chromeos" | "unknown"
|
|
28
|
+
Everywhere.native // true inside a RubyEverywhere app
|
|
29
|
+
Everywhere.version // app version; null in a plain browser tab
|
|
30
|
+
|
|
31
|
+
Everywhere.notify({ title, body }) // native notification / web Notification / console
|
|
32
|
+
Everywhere.confirm("Sure?") // Promise<boolean>, native dialog when possible
|
|
33
|
+
Everywhere.on("menu", handler) // shell events; returns an unsubscribe fn
|
|
34
|
+
Everywhere.visit("/settings") // Turbo.visit with location fallback
|
|
35
|
+
|
|
36
|
+
Everywhere.clipboard.write(text) // Promise<void>
|
|
37
|
+
Everywhere.clipboard.read() // Promise<string | null>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Auto-updates
|
|
41
|
+
|
|
42
|
+
Inside the desktop shell, apps with an update feed configured can check,
|
|
43
|
+
install, and switch channels at runtime:
|
|
44
|
+
|
|
45
|
+
```js
|
|
46
|
+
Everywhere.updates.supported // true when the shell has an update feed
|
|
47
|
+
Everywhere.updates.channel // effective channel ("stable", "beta", …)
|
|
48
|
+
|
|
49
|
+
const result = await Everywhere.updates.check()
|
|
50
|
+
// { available: true, version, notes, notesHtml } or { available: false }
|
|
51
|
+
|
|
52
|
+
Everywhere.updates.install() // download / verify / swap / relaunch
|
|
53
|
+
Everywhere.updates.setChannel("beta") // Promise<{ channel }>, persisted by the shell
|
|
54
|
+
|
|
55
|
+
Everywhere.updates.on("available", handler)
|
|
56
|
+
// events: "available" | "none" | "progress" | "ready" | "error" | "channel"
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
`notes` is the release-notes markdown source; `notesHtml` is the same notes
|
|
60
|
+
pre-rendered to HTML from your signed update feed, ready for a changelog
|
|
61
|
+
modal: `el.innerHTML = notesHtml`.
|
|
62
|
+
|
|
63
|
+
In a plain browser tab the updates API is inert: `check()` resolves
|
|
64
|
+
`{ available: false, unsupported: true }` and nothing throws.
|
|
65
|
+
|
|
66
|
+
## Platforms
|
|
67
|
+
|
|
68
|
+
- **desktop** — the Tauri-based RubyEverywhere shell. Notifications, dialogs,
|
|
69
|
+
clipboard, shell events, and auto-updates are native.
|
|
70
|
+
- **browser** — honest web fallbacks: the Notification API, `window.confirm`,
|
|
71
|
+
`navigator.clipboard`, DOM CustomEvents.
|
|
72
|
+
- **mobile** — Hotwire Native detection is live; behavior currently falls back
|
|
73
|
+
to the browser adapter until the bridge-component adapter lands.
|
|
74
|
+
|
|
75
|
+
## License
|
|
76
|
+
|
|
77
|
+
MIT
|
data/bridge/package.json
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rubyeverywhere/bridge",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "One API for browser, desktop, and mobile — the JS half of RubyEverywhere",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "everywhere/bridge.js",
|
|
7
|
+
"exports": { ".": "./everywhere/bridge.js" },
|
|
8
|
+
"files": ["everywhere/bridge.js", "README.md"],
|
|
9
|
+
"sideEffects": false,
|
|
10
|
+
"keywords": ["rubyeverywhere", "tauri", "hotwire", "turbo", "rails", "desktop", "native", "bridge"],
|
|
11
|
+
"homepage": "https://rubyeverywhere.com",
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"publishConfig": { "access": "public" }
|
|
14
|
+
}
|
data/config/importmap.rb
ADDED
|
@@ -66,7 +66,7 @@ module Everywhere
|
|
|
66
66
|
# Rack frameworks vary too much to auto-edit their boot files safely, so we
|
|
67
67
|
# vendor the bridge and print the remaining wiring rather than guess.
|
|
68
68
|
def vendor_bridge_to_public
|
|
69
|
-
source = File.expand_path("
|
|
69
|
+
source = File.expand_path("../../../bridge/everywhere/bridge.js", __dir__)
|
|
70
70
|
target_dir = app_file("public")
|
|
71
71
|
FileUtils.mkdir_p(target_dir)
|
|
72
72
|
target = File.join(target_dir, "bridge.js")
|
|
@@ -219,32 +219,36 @@ module Everywhere
|
|
|
219
219
|
change("disable force_ssl for localhost", made)
|
|
220
220
|
end
|
|
221
221
|
|
|
222
|
-
#
|
|
223
|
-
# and
|
|
224
|
-
#
|
|
222
|
+
# @rubyeverywhere/bridge (one JS API across browser/desktop/mobile) is
|
|
223
|
+
# served and pinned by Everywhere::Engine straight from the gem, so the
|
|
224
|
+
# bridge updates with `bundle update ruby_everywhere`. Nothing to vendor —
|
|
225
|
+
# just migrate apps installed before the engine existed (their vendored
|
|
226
|
+
# copy and pin would shadow the engine's, freezing them on an old bridge)
|
|
227
|
+
# and wire the import.
|
|
225
228
|
def install_bridge
|
|
226
|
-
|
|
227
|
-
target_dir = app_file("vendor", "javascript")
|
|
228
|
-
target = File.join(target_dir, "@rubyeverywhere--bridge.js")
|
|
229
|
-
FileUtils.mkdir_p(target_dir)
|
|
230
|
-
# Stamp a machine-readable version marker on the vendored copy so the
|
|
231
|
-
# build receipt (Receipt#bridge_version) can record which bridge shipped.
|
|
232
|
-
# Comparing against the fully-stamped content keeps re-runs idempotent.
|
|
233
|
-
desired = "// @rubyeverywhere/bridge version: #{Everywhere::BRIDGE_VERSION} (vendored by `every install`)\n#{File.read(source)}"
|
|
234
|
-
fresh = !File.exist?(target) || File.read(target) != desired
|
|
235
|
-
File.write(target, desired) if fresh
|
|
229
|
+
fresh = remove_vendored_bridge
|
|
236
230
|
|
|
237
231
|
importmap = app_file("config", "importmap.rb")
|
|
238
232
|
if File.exist?(importmap)
|
|
239
233
|
contents = File.read(importmap)
|
|
240
|
-
|
|
241
|
-
|
|
234
|
+
stale_pin = /^pin ["']@rubyeverywhere\/bridge["'],\s*to:\s*["']@rubyeverywhere--bridge\.js["'].*\n/
|
|
235
|
+
if contents.match?(stale_pin)
|
|
236
|
+
File.write(importmap, contents.gsub(stale_pin, ""))
|
|
242
237
|
fresh = true
|
|
243
238
|
end
|
|
244
239
|
end
|
|
245
240
|
wire_application_js(fresh)
|
|
246
241
|
end
|
|
247
242
|
|
|
243
|
+
def remove_vendored_bridge
|
|
244
|
+
target = app_file("vendor", "javascript", "@rubyeverywhere--bridge.js")
|
|
245
|
+
return false unless File.exist?(target)
|
|
246
|
+
|
|
247
|
+
FileUtils.rm(target)
|
|
248
|
+
change("remove vendored bridge (now served by the ruby_everywhere engine)", true)
|
|
249
|
+
true
|
|
250
|
+
end
|
|
251
|
+
|
|
248
252
|
def wire_application_js(fresh)
|
|
249
253
|
app_js = app_file("app", "javascript", "application.js")
|
|
250
254
|
if File.exist?(app_js)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Everywhere
|
|
4
|
+
# Rails integration: serves @rubyeverywhere/bridge straight from the gem's
|
|
5
|
+
# bridge/ directory (the same files published to npm — single source) and
|
|
6
|
+
# contributes the importmap pin, so apps get bridge updates with
|
|
7
|
+
# `bundle update ruby_everywhere` — no vendored copy to refresh. Loaded only
|
|
8
|
+
# when Rails is present; Sinatra/Hanami apps keep the vendored
|
|
9
|
+
# public/bridge.js from `every install`.
|
|
10
|
+
class Engine < ::Rails::Engine
|
|
11
|
+
# bridge/ becomes an asset root, so bridge/everywhere/bridge.js gets the
|
|
12
|
+
# namespaced logical path "everywhere/bridge.js" (Propshaft and Sprockets
|
|
13
|
+
# both read config.assets.paths); Sprockets additionally needs the file
|
|
14
|
+
# declared precompilable.
|
|
15
|
+
initializer "everywhere.assets" do |app|
|
|
16
|
+
if app.config.respond_to?(:assets)
|
|
17
|
+
app.config.assets.paths << Engine.root.join("bridge").to_s
|
|
18
|
+
app.config.assets.precompile += %w[everywhere/bridge.js] if app.config.assets.respond_to?(:precompile)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Runs before importmap-rails adds the app's config/importmap.rb, so an
|
|
23
|
+
# app-level pin (e.g. a legacy vendored copy) still overrides ours.
|
|
24
|
+
initializer "everywhere.importmap", before: "importmap" do |app|
|
|
25
|
+
if app.config.respond_to?(:importmap)
|
|
26
|
+
app.config.importmap.paths << Engine.root.join("config/importmap.rb")
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
data/lib/everywhere/receipt.rb
CHANGED
|
@@ -116,10 +116,18 @@ module Everywhere
|
|
|
116
116
|
File.join(@root, "vendor", "javascript", "@rubyeverywhere", "bridge", "package.json")
|
|
117
117
|
].each { |p| (v = json_version(p)) and return v }
|
|
118
118
|
|
|
119
|
-
#
|
|
120
|
-
#
|
|
119
|
+
# Legacy single-file vendored install: read the `// version: x.y.z`
|
|
120
|
+
# marker `every install` stamped on the copy.
|
|
121
121
|
flat = File.join(@root, "vendor", "javascript", "@rubyeverywhere--bridge.js")
|
|
122
|
-
|
|
122
|
+
return File.foreach(flat).first(6).join[/version:\s*([\d.]+)/i, 1] if File.exist?(flat)
|
|
123
|
+
|
|
124
|
+
# Engine-served (Rails apps bundling ruby_everywhere): the bridge ships
|
|
125
|
+
# inside the gem, so it carries the gem's BRIDGE_VERSION. Best-effort —
|
|
126
|
+
# assumes the app bundles the same gem release that's running this build.
|
|
127
|
+
lock = File.join(@root, "Gemfile.lock")
|
|
128
|
+
return Everywhere::BRIDGE_VERSION if File.exist?(lock) && File.read(lock).match?(/^\s+ruby_everywhere\s/)
|
|
129
|
+
|
|
130
|
+
nil
|
|
123
131
|
end
|
|
124
132
|
|
|
125
133
|
def shell_version
|
data/lib/everywhere/version.rb
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Everywhere
|
|
4
|
-
VERSION = "0.1.
|
|
4
|
+
VERSION = "0.1.10"
|
|
5
5
|
|
|
6
|
-
# Version of the
|
|
7
|
-
#
|
|
8
|
-
#
|
|
9
|
-
#
|
|
10
|
-
|
|
6
|
+
# Version of the @rubyeverywhere/bridge JS this gem ships. bridge/ in the
|
|
7
|
+
# gem IS the npm package (served to Rails apps by Everywhere::Engine,
|
|
8
|
+
# vendored to public/ for Sinatra/Hanami), so its package.json is the single
|
|
9
|
+
# source of truth. The build receipt records it; it versions independently
|
|
10
|
+
# of the CLI.
|
|
11
|
+
BRIDGE_VERSION = File.read(
|
|
12
|
+
File.expand_path("../../bridge/package.json", __dir__)
|
|
13
|
+
)[/"version":\s*"([^"]+)"/, 1]
|
|
11
14
|
end
|
data/lib/everywhere.rb
CHANGED
|
@@ -7,6 +7,9 @@ require_relative "everywhere/config"
|
|
|
7
7
|
require_relative "everywhere/framework"
|
|
8
8
|
require_relative "everywhere/database"
|
|
9
9
|
require_relative "everywhere/boot"
|
|
10
|
+
# Rails apps get the bridge served + pinned by the engine (Sinatra/Hanami
|
|
11
|
+
# vendor it to public/ instead — see `every install`).
|
|
12
|
+
require_relative "everywhere/engine" if defined?(::Rails::Engine)
|
|
10
13
|
|
|
11
14
|
module Everywhere
|
|
12
15
|
class Error < StandardError; end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ruby_everywhere
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.10
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andrea Fomera
|
|
@@ -75,6 +75,10 @@ executables:
|
|
|
75
75
|
extensions: []
|
|
76
76
|
extra_rdoc_files: []
|
|
77
77
|
files:
|
|
78
|
+
- bridge/README.md
|
|
79
|
+
- bridge/everywhere/bridge.js
|
|
80
|
+
- bridge/package.json
|
|
81
|
+
- config/importmap.rb
|
|
78
82
|
- exe/every
|
|
79
83
|
- exe/rbe
|
|
80
84
|
- lib/everywhere.rb
|
|
@@ -98,10 +102,10 @@ files:
|
|
|
98
102
|
- lib/everywhere/commands/updates_keygen.rb
|
|
99
103
|
- lib/everywhere/config.rb
|
|
100
104
|
- lib/everywhere/database.rb
|
|
105
|
+
- lib/everywhere/engine.rb
|
|
101
106
|
- lib/everywhere/framework.rb
|
|
102
107
|
- lib/everywhere/icon.rb
|
|
103
108
|
- lib/everywhere/ignore.rb
|
|
104
|
-
- lib/everywhere/javascript/bridge.js
|
|
105
109
|
- lib/everywhere/log_filter.rb
|
|
106
110
|
- lib/everywhere/minisign.rb
|
|
107
111
|
- lib/everywhere/paths.rb
|
|
File without changes
|