@lampdotdev/lamp 0.36.2-nightly.21 → 0.36.2-nightly.23

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
@@ -26,7 +26,7 @@ Mac app, `projectOf`), or any folder with an `index.html`; without one, the fold
26
26
  | `lamp use key w 2` | Tries it as a person would, then looks: `click`, `type`, `key` (several at once with `w+d`), `drag`, `scroll`, `wait`, and in a game on Lamp's runtime `stick` and `button`, which hold Lamp's own controller as Lamp's app does (`window.__lampDrive`) and give it back when the person plays. Several moves with `then` between them go one after another, with one look at the end. |
27
27
  | `lamp reload [--fresh]` | Opens the page again from its files, a game from where the player is, or with `--fresh` from its beginning (`window.lampFreshStart`). |
28
28
  | `lamp stop` | Stops running it. |
29
- | `lamp share --words "…"` | Puts the page on lamp.dev: anyone with the link plays it there and can send an idea. Again, it sends the page as it is now to the same link. |
29
+ | `lamp share --words "…"` | Puts the page on lamp.dev: anyone with the link plays it there and can send an idea. Again, it sends the page as it is now to the same link. The app's icon goes with it (`iconOf`: a square `icon.png` or `apple-touch-icon.png` beside the page, a PNG its index.html names as its icon, or Lamp's `.lamp/icon.png`, made 512 pixels a side when bigger), for its page and the browser's tab. |
30
30
  | `lamp share` (a page of Lamp's) | A web app or game in a Lamp's own folder is lamp's to share like any other page, Lamp open or not, to the link that Lamp keeps for it: lamp takes the link from the Lamp's `Wish Links.json` (by the app's instance id in `.lamp/meta.json`, `lampsKeptLink`) the first time, and tells it what went after each share or `unshare` (`keepInLamp`), so its Share Link card shows the link as it is. `ideas` and `unshare` take the link the same way. |
31
31
  | `lamp share` (any other app of Lamp's) | For a folder in Lamp's own (or a link to one) that lamp doesn't share as a page, shared by Lamp's app over its socket (`share_link`, `OutsideWork`): its Share Link card filled as it fills itself (`WishLinkCards.prepare`: the link's last words, the questions and what's new Lamp writes, the app's file, the GitHub release) and shared without its window, with `--line`, `--by`, `--asks`, `--notes`, `--no-file`, `--no-github`, `--put-on-github` in place of the card's own, and `--preview` to see it first. The link's secret stays in Lamp. Which Lamp is the one whose folder it is (`lampOwning`), or the one it was given to (`lamp open --in-lamp`, `givenTo`); any other folder is lamp's to share, whatever Lamp is running, and so is a given folder when its Lamp is too old to share for lamp. |
32
32
  | `lamp ideas [in <n> \| dismiss <n> \| reply <n> \| done <n> \| email <address\|off>] [note]` | The ideas people playing the link have sent and what's been said since, saying what became of one, and answering whoever sent it. |
@@ -1 +1 @@
1
- {"exe":"ZqxAppName","name":"Zqx App Name","instance":"66001C8E-04AF-4B31-9585-64F312C02625","platform":"mac"}
1
+ {"instance":"916F96D1-7682-461F-A3F0-F35A508564DB","exe":"ZqxAppName","name":"Zqx App Name","platform":"mac"}
package/cli/share.mjs CHANGED
@@ -7,15 +7,16 @@
7
7
 
8
8
  import { execFileSync } from "node:child_process";
9
9
  import { createHash } from "node:crypto";
10
- import { existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from "node:fs";
10
+ import { existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, realpathSync, rmSync, writeFileSync } from "node:fs";
11
11
  import { homedir } from "node:os";
12
- import { basename, dirname, join, resolve } from "node:path";
12
+ import { basename, dirname, join, resolve, sep } from "node:path";
13
13
  import { deflateRawSync } from "node:zlib";
14
14
  import { NOTES_FILE, Problem, stateOf } from "./state.mjs";
15
15
  import { ANY_BROWSER, CONTROLLERS, CONTROLLERS_FILE, DEVICE_FILE, lampJS, LIBRARIES } from "./dev.mjs";
16
16
  import { LIMITS, FILE_LIMITS, PAGE_LIMITS } from "../site/lib/shared-wishes.js";
17
17
  import { ideasOf, makerOf, pageUp, publishLink, removeFile, removeIdea, removeLink, replyIdea, sendFile, siteOrigin } from "./link.mjs";
18
18
  import { exportApp, sourceLinkOf } from "./lampapp.mjs";
19
+ import { scaled, sizeOf } from "./png.mjs";
19
20
 
20
21
  export { siteOrigin };
21
22
 
@@ -175,6 +176,40 @@ const megabytes = (bytes) => `${(bytes / 1_000_000).toFixed(bytes < 10_000_000 ?
175
176
  * are what the link says (`name`, `words`, and `line`, `by` and `asks` when given), `picture` a PNG or JPEG of the
176
177
  * page or null, `shape` "fill" or the page's width over its height. Answers the link and what went up.
177
178
  */
179
+ /**
180
+ * The app's own icon for its link: a square PNG the page has (icon.png or apple-touch-icon.png beside it, or a PNG its
181
+ * index.html names as its icon), else the one Lamp keeps in its own app's folder (.lamp/icon.png). Made 512 pixels a side
182
+ * when it's bigger than the site takes. Null when there's none that's square: a page's own picture is never squashed.
183
+ */
184
+ export function iconOf(layout) {
185
+ const names = ["icon.png", "apple-touch-icon.png"];
186
+ try {
187
+ const html = readFileSync(join(layout.root, "index.html"), "utf8");
188
+ for (const tag of html.match(/<link\b[^>]*>/gi) ?? []) {
189
+ const href = /\bhref=["']([^"'?#]+\.png)["']/i.exec(tag)?.[1];
190
+ if (/\brel=["'][^"']*\bicon\b/i.test(tag) && href && !/^[a-z]+:|^\/\//i.test(href)) names.push(href.replace(/^\.?\//, ""));
191
+ }
192
+ } catch {}
193
+ const candidates = [...names.map((name) => join(layout.root, name)), join(layout.folder, ".lamp", "icon.png")];
194
+ // Only a file really in the app's folder, links followed: a name like ../elsewhere.png or a link out of the folder
195
+ // would put someone's other picture on a public page.
196
+ let home;
197
+ try { home = realpathSync(layout.folder); } catch { return null; }
198
+ for (const file of candidates) {
199
+ let real;
200
+ try { real = realpathSync(file); } catch { continue; }
201
+ if (!real.startsWith(home + sep)) continue;
202
+ let bytes;
203
+ try { bytes = readFileSync(real); } catch { continue; }
204
+ const size = sizeOf(bytes);
205
+ if (!size || size.width !== size.height || size.width < 16) continue;
206
+ if (size.width <= 512 && bytes.length <= LIMITS.icon) return bytes;
207
+ const smaller = scaled(bytes, 512);
208
+ if (smaller && smaller.length <= LIMITS.icon) return smaller;
209
+ }
210
+ return null;
211
+ }
212
+
178
213
  export async function share({ layout, words, picture = null, shape = "fill", site = siteOrigin(), said = () => {}, file = true, anyway = false, github, fromLamp = false }) {
179
214
  // The folder's own link when it has one on this site, changed in place; a link that's gone is made again.
180
215
  let earlier = readLink(layout.folder);
@@ -200,6 +235,9 @@ export async function share({ layout, words, picture = null, shape = "fill", sit
200
235
  ...(words.asks?.length ? { asks: words.asks } : {}), ...(picture ? { picture: picture.toString("base64") } : {}),
201
236
  ...(repo ? { github: repo } : {}),
202
237
  };
238
+ // The app's icon, which its page shows beside its name and in the browser's tab, as Lamp's Share Link sends it.
239
+ const icon = iconOf(layout);
240
+ if (icon) body.icon = icon.toString("base64");
203
241
  // The link this app came from, when it's a copy of one shared there: its page says so.
204
242
  const from = sourceLinkOf(layout.folder, site, earlier?.id);
205
243
  if (from) body.from = from;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lampdotdev/lamp",
3
- "version": "0.36.2-nightly.21",
3
+ "version": "0.36.2-nightly.23",
4
4
  "description": "Runs a web app or game from its folder and puts each saved change into the open page.",
5
5
  "type": "module",
6
6
  "bin": {