浏览器侧文件下载如果简单的blob对象,然后调用URL.createObjectURL(blob)方法,会直接下载文件。但是坏处是无法支持大文件下载。在不改变后端的基础上如何解决呢。streamSaver.js就是为了解决这个问题而诞生的。

原理

streamSaver.js利用serviceworker来实现请求拦截,而请求如果结果是stream则可以直接持续写入浏览器侧本地,这样就可以打破JS单线程限制,无法下载大文件及阻塞线程。

使用

1
2
3
4
5
6
7
8
9
10
import streamSaver from 'streamsaver';

streamSaver.mitm = 'https://example.com/custom_mitm.html'

const fileStream = streamSaver.createWriteStream('hello.mkv', { size: 10_000_000 });
const fileWriter = fileStream.getWriter();

fileWriter.write(new Uint8Array(chunk));

fileWriter.close();
阅读全文 »

因为工作需要,使用过很多终端,比如iTerm2,Warp,Tabby,Hyper等。

最近调研下Wave Terminal,觉得也有些亮点,这里就介绍下。

平台

Wave 是一款本地终端,非Web,目前支持

  1. MacM系列也支持
  2. Linux
  3. Windows WSLWindows也可以!
阅读全文 »

OpenAI官方发布了GPT 4o mini,在快速使用后,这里介绍下它的基本情况。

定位

GPT 4o mini的推出是为了替代GPT 3.5,因为其比3.5便宜60%,但是又更为聪明。因此当我们在使用GPT3.5的场景都可以直接切换到GPT 4o mini。

阅读全文 »

调用AI服务,经常需要处理流返回结果,当出现异常时也是需要流处理的,这点与非流情况下的异常处理有所不同。

举个🌰

这里以axios为例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
axios.post('http://api.com/v1/chat/completions', data, {
headers: {
Authorization: `Bearer xxxx`,
'Content-Type': 'application/json',
},
responseType: 'stream',
}).then(res => res.data)
.catch(async (e) => {
let error;
if (e.isAxiosError) {
let streamString = '';
await new Promise(resolve => {
e.response.data
.on('data', (utf8Chunk) => {
streamString += utf8Chunk;
})
.on('end', () => {
error = JSON.parse(streamString);
resolve();
});
})
} else {
error = e;
}
throw error;
});

可以看到stream情况下对于异常也要流方式处理,因为流处理是事件监听机制, 因此这里promise化处理了下,避免error值获取不正确。

阅读全文 »

今年喜欢上玩多邻国,虽然谈不上提高了多少,但巩固了下基础词汇,训练了下听力挺好的,并且也并没有花费多少时间,平均1天也就十几分钟到几分钟。

这里介绍下我是如何使用多邻国的。

平台

多邻国是跨平台的,Android,iOS,Web网页均支持,无Mac版。

我个人主要是用iOS版,其次是Web版。

免费/付费?

阅读全文 »

最近调研Google IAP,玩了下Google云机器登录,这里Mark下。

注册

  1. GMail

  2. 绑定支付,如果不绑定支付的话,无法购买机器。

    1
    初次赠送的赠金有有效期,过期后,金额还显示,但实际支付是不会抵扣的。

    实际测试Visa没问题

创建机器

以虚拟机实例为例,机器按秒计费,但注意单位是刀的话,还是挺贵的,临时使用的话,注意及时销毁。

阅读全文 »

安装php7.3

1
2
3
4
5
6
7
8
sudo yum install epel-release -y
sudo yum install https://rpms.remirepo.net/enterprise/remi-release-7.rpm -y
sudo yum install yum-utils -y
sudo yum-config-manager --enable remi-php73
sudo yum install php php-cli php-fpm php-mysqlnd php-json php-opcache php-xml php-mbstring php-tokenizer php-curl php-zip php-gd -y

# 检查版本
php -v

MySQL8

1
2
3
4
5
6
7
8
9
10
11
yum localinstall -y https://dev.mysql.com/get/mysql80-community-release-el7-2.noarch.rpm
yum install -y mysql-community-server

rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2023


# 获取临时密码
grep 'temporary password' /var/log/mysqld.log

# 初始化DB配置

阅读全文 »

线上发布Web为了方便追溯用户的具体报错,我们会开启SourceMap,是发包发布时会将SourceMap上传到我们的RUM平台,这样当用户出现报错时,通过RUM平台上的SourceMap也可以追溯到源码的报错位置。但也并非构建打包的所有文件都需要生成sourcemap,那么如何定制呢?

开启SourceMap

Webpack中,简单点呢的话会是如下配置。

1
2
3
4
5
{
...
devtool: 'source-map',
...
}

这样做的弊端是所有的JS文件都会生成SourceMap,如果我们想排除某些呢,比如我们懒加载第三方模块,比如MonacoEditor。Webpack也是支持定制化SourceNap生成的。

阅读全文 »

在处理文本文件时会遇到行分割符的不同,这里为什么有这种差异和如何处理呢,这里mark下。

系统差异

Windows是\r\n,而Unix/macOS是\n

比如在Windows中使用NotePad创建文本文件,保存后,拖动到VSC等编辑器中打开,可以看到提示分割符是\r\n。

编辑器里的设置

阅读全文 »

在翻看inshellinsense代码时看到is建立本地终端时有控制加载指定目录下的启动文件。因此我在想SSH2连接Web 终端会话是否也可以呢,这里讨论下可行性。

inshellisense的做法

以bash为例

1
2
3
4
5
6
7
8
9
shellArgs = ["--init-file", path.join(shellFolderPath, "shellIntegration.bash")];

this.#pty = pty.spawn(shellTarget, shellArgs ?? [], {
name: "xterm-256color",
cols,
rows,
cwd: process.cwd(),
env: { ...convertToPtyEnv(shell, underTest, login), ...env },
});

可以看到实现的原理是spawn的第二个参数传入了shell参数,比如bash有–init-file参数

阅读全文 »
0%