<button> 與 <input type="button"> 的差異

在追奇怪的問題時發現的,實際上是個當年沒學好 (或是太久沒用忘記了),現在回頭重新學的東西,在 Stack Overflow 上很久前就有人問過了:「<button> vs. <input type="button"> -- which to use?」。

我遇到的問題是 <button> 預設會觸發 submit 事件 (<input type="button"> 不會,然後我以為 <button> 也不會)。

而這邊又遇到 <button> 上綁定了 click() 事件的後續行為在 ChromiumFirefox 不同。

我在 click() 事件裡修改某些 input field 後想要觸發 submit() 事件時透過 document.querySelector('#second_submit_button').click() 觸發第二個 submit 按鈕,但在 Chromium 上會走到第一個 submit,而在 Firefox 上則是會走第二個 submit...

不確定這種複雜的行為是怎麼被定義的 (也蠻有機會是沒定義的),所以只先查了比較單純的東西。

首先是現代的 HTML 規格中定義 <button> 的行為是在「The button element」這邊,裡面提到:

The type attribute controls the behavior of the button when it is activated. It is an enumerated attribute with the following keywords and states:

中間列了一張表列出 type 可以設定的值,然後說如果沒有指定 type 的話就是 submit:

The attribute's missing value default and invalid value default are both the Submit Button state.

If the type attribute is in the Submit Button state, the element is specifically a submit button.

知道為什麼後就能夠規劃解法了,解法看起來有兩條路:

第一條是用 <input type="button">,這樣就不會觸發瀏覽器的預設 submit 行為,就不會有後續的分支要處理。

第二條是用 event.preventDefault() 躲開問題,就... 會動。

不過這代表小時候沒學好啊... 如果我記得 <button> 預設會 submit 的話,我就會習慣用 <input type="button">,避免常態性中獎 @_@

Node.js 實驗性支援 type 的語法 (但不會檢查)

Hacker News 上看到「Node.js adds experimental support for TypeScript (github.com/nodejs)」這個,標題有點誤導就是了,GitHub 上面的標題比較正確:「module: add --experimental-strip-types」。

從說明可以看到 --experimental-strip-types 參數只是接受 type 語法,但不會檢查:

It is possible to execute TypeScript files by setting the experimental flag --experimental-strip-types.

Node.js will transpile TypeScript source code into JavaScript source code.

During the transpilation process, no type checking is performed, and types are discarded.

目前的版本離跑 TypeScript 還有段距離,不過算是個有趣的開頭:

At least initially in this PR no trasformation is performed, meaning that using Enum, namespaces etc... will not be possible.

不確定官方打算要支援 TypeScript,還是只是個人作個實驗看看?

Amazon EC2 推出 Graviton4 的機種 r8g.*

Amazon EC2 推出了 Graviton4 的新機種:「AWS Graviton4-based Amazon EC2 R8g instances: best price performance in Amazon EC2」。

第一波 Graviton4 的機種是 R 系列的機器,r8g.*,依照官方說法有機會到 30% 的效能提升:

AWS Graviton4-based Amazon EC2 R8g instances deliver up to 30% better performance than AWS Graviton3-based Amazon EC2 R7g instances.

價錢的部分翻了一下,貴了 10% 左右。另外機器大小上限也有改變,之前 r7g.metal 是 64 vCPU + 512GB RAM,這次 r8g.metal-24xl 是 96 vCPU + 768GB RAM,另外還有 r8g.metal-48xl 的 192 vCPU + 1536GB RAM 的版本,上限拉到原來的三倍。

話說 t4g 還是 Graviton2 的機種呢,什麼時候有機會用到 t5g 呢...

RFC 9512:application/yaml

看到「RFC 9512: YAML Media Type」這個,原來還沒有註冊 application/yaml 啊...

另外在 media type 的文件裡面,意外的給出了安全性的建議:

Code execution in deserializers should be disabled by default and only be enabled explicitly. In the latter case, the implementation should ensure (for example, via specific functions) that the code execution results in strictly bounded time/memory limits.

這邊用的是 should 不是 SHOULD,所以當一般的英文句子在讀,而非具有規範性的敘述。

但還是給了預設關閉 code execution 的建議...

輸出 7.5V 的 USB Type A 頭

Hacker News Daily 上看到的:「My cat water fountain comes with a spicy USB power adapter (ounapuu.ee)」,原文在「My cat water fountain comes with a spicy USB power adapter」。

作者的貓咪飲水噴泉用的是 USB Type A 的頭供電:

但仔細看會發現是特規,輸出 7.5V:

如果隨便收起來亂接的話應該會燒掉不少東西...

Raspberry Pi 5 的一些細節出現了...

上一篇「Raspberry Pi 5」提到了一些來自 Raspberry Pi 官方的說明,後續各個媒體 (像是 YouTuber) 也都解禁放出不少資料可以參考了,其中電源的部分在「Answering some questions about the Raspberry Pi 5」這邊看到不認 USB PD 的 5V/5A 的問題,目前看起來是走獨規:

I also tested the Radxa USB-C PD 30W power adapter, which says it will output 5V at 5A, but the Pi only negotiates 3A with it right now. I've been in contact with Pi engineers and it seems like they have one on the way to test to see why it's not negotiating more.

另外看起來之後有機會支援 12V/2.25A (換算起來是 27W) 的充電頭,有機會透過韌體更新認得 PD?

I should also note the official adapter lists 12V at 2.25A output as an option, so maybe some future Pi could take that and run with it, for increased compatibility with more USB-C PD adapters (5V at 5A is a rarely seen, though it's an option in the spec).

不過即使走 5V/3A (15W),在一般的應用下是夠用了,到時候拿到來玩看看...

WordPress 誕生 20 年

Matt Mullenweg 寫了一篇文章簡單提到 WordPress 誕生 20 年:「WP20 & Audrey Scholars」。

雖然 Matt Mullenweg 在文章裡都沒提到,但 WordPress 的興起其實跟當年 2004 年最大的 blog 軟體 Movable Type 自己出的包有很大的關係:

With the release of version 3.0 in 2004, there were marked changes in Movable Type's licensing, most notably placing greater restrictions on its use without paying a licensing fee. This sparked criticism from some users of the software, with some moving to the then-new open-source blogging tool WordPress. With the release of Movable Type 3.2, the ability to create an unlimited number of weblogs at all licensing levels was restored. In Movable Type 3.3, the product once again became completely free for personal users.

當年 hlb 在社團主機上用 Movable Type 架了服務讓大家寫,結果後來發生了 license 問題,大家就都順勢跑到 WordPress 上了;而等到 Movable Type 再次想放寬 license 的時候已經來不及了,大家都已經搬完了。

翻了一下最舊的文章 (在另外一個 WordPress 上) 是在 2004 年十月的時候寫的,就有提到當時從 Movable Type 換到 WordPress 的考量:「開場:為什麼用 WordPress」。

用 Automerge 處理 CRDT 問題

上個月看到 Automerge 出了 2.0 版的消息:「Automerge 2.0」,Automerge 這個套件可以幫你處理複雜的 CRDT 結構 (Conflict-free replicated data type)。

可以看到 Automerge 在 2.0 之後的效能改善不少,可以跟 yjs 比較了:

所以練了一下手測界面怎麼用,另外也看一下 conflict 時的處理方式。

這邊先產生 hello, world.,然後做了三個操作,第一個是把開頭的 h 改成 H;第二個是把 world 改成 test;第三個是把 world 改成 example

(() => {
  const Automerge = require('@automerge/automerge');

  let doc1 = Automerge.init();

  doc1 = Automerge.change(doc1, 'Init', doc => {
    doc.text = new Automerge.Text();
    doc.text.insertAt(0, 'h', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '.');
  });
  
  let doc2 = Automerge.clone(doc1);
  let doc3 = Automerge.clone(doc1);

  doc1 = Automerge.change(doc1, 'Capitalize', doc => {
    doc.text.deleteAt(0);
    doc.text.insertAt(0, 'H');
  });
  doc2 = Automerge.change(doc2, 'world => test', doc => {
    delete doc.text.deleteAt(7, 5);
    doc.text.insertAt(7, 'test');
  });
  doc3 = Automerge.change(doc3, 'world => example', doc => {
    delete doc.text.deleteAt(7, 5);
    doc.text.insertAt(7, 'example');
  });

  let finalDoc = Automerge.merge(doc1, doc2);
  finalDoc = Automerge.merge(finalDoc, doc3);
  console.log(finalDoc);
})();

這樣最後會產生出 Hello, testexample.

{
  text: Text {
    elems: [
      'H', 'e', 'l', 'l', 'o',
      ',', ' ', 't', 'e', 's',
      't', 'e', 'x', 'a', 'm',
      'p', 'l', 'e', '.'
    ]
  }
}

這結果看起來還行。

只能說以前要是有這些 library 就好了,當初在 KKBOX 做雲端歌單自己搞半天...

Amazon EC2 的 Trn1 正式開放使用

AWS 自家研發晶片的 trn1.* 上線了:「Amazon EC2 Trn1 Instances for High-Performance Model Training are Now Available」。

先前三家雲端的廠商只有 Google Cloud PlatformTPU 可以 train & evaluate,現在 AWS 推出 AWS Trainium,補上 train 這塊的產品。其中官方宣稱可以比 GPU 架構少 50% 的計算成本:

Trainium-based EC2 Trn1 instances solve this challenge by delivering faster time-to-train while offering up to 50% cost-to-train savings over comparable GPU-based instances.

然後 PyTorchTensorFlow 都有支援:

The Neuron plugin natively integrates with popular ML frameworks, such as PyTorch and TensorFlow.

另外用 neuron-ls 可以看到 Neuron 裝置的資訊,不過沒看懂為什麼要 mask 掉 private ip 的資訊:

大型的 cluster 會使用 Amazon FSx for Lustre 整合提供服務:

For large-scale model training, Trn1 instances integrate with Amazon FSx for Lustre high-performance storage and are deployed in EC2 UltraClusters. EC2 UltraClusters are hyperscale clusters interconnected with a non-blocking petabit-scale network.

但第一波開放的區域有點少,只有萬年美東一區 us-east-1 與美西二區 us-west-2

You can launch Trn1 instances today in the AWS US East (N. Virginia) and US West (Oregon) Regions as On-Demand, Reserved, and Spot Instances or as part of a Savings Plan.

us-east-1trn1.2xlarge 的價錢是 US$1.34375/hr,但沒有實際跑過比較好像沒辦法評估到底行不行...

但總算是擺出個產品對打看看,畢竟要夠大才能去訂製這些東西。

目前 AWS 台北區只能開 *.2xlarge 的機器

前面在「AWS 的台北區 (Local Zone) 開了」這邊有提到機器開不起來,剛剛查價錢的時候才發現只能開 {c5,g4dn,m5,r5}.2xlarge

改成 c5.2xlarge 然後就開起來了:

翻了目前所有的 local zone,看起來大多都是類似的情況,選擇性會很少... 目前只有邁阿密與洛杉磯的選擇比較多,這是邁阿密:

這是洛杉磯:

這樣目前要拿來當 VPS 取代品還不太好用,就真的是 local zone 的定位。