吴细小
用于工作的小工具箱 卫生 javaScript 和 TypeScript 中的突变
免责声明: 这项工作正在进行中,要冒着风险使用!
看着
- 可声明和可相容突变创建者
- 对内存文件应用突变装置(实验性)
- 支持乐观更新的本地内存数据集复制(实验)
特征
- 变异可以使用创建功能宣告,并像任何其他价值观一样相传,被转化和构成 进入涵盖多个文件的大型行动
- 突变只是操作的描述,可以被序列化为紧凑的json格式或Sanity突变 API 请求有效载荷
- 节点可以通过路径作为 JavaScript 值处理,而不是字符串路径
- 与 Sanity.io 变异格式
- 支持自动添加
_key'是数组中的对象,所以你不必. - 实验性支持在记忆文件中应用突变
- 大类型脚本支持
用法示例
import {
at,
create,
createIfNotExists,
patch,
SanityEncoder,
set,
setIfMissing,
} from '@bjoerge/mutiny'
const mutations = [
create({_type: 'dog', name: 'Fido'}),
createIfNotExists({_id: 'document-1', _type: 'someType'}),
createIfNotExists({_id: 'other-document', _type: 'author'}),
patch('other-document', [
at('published', set(true)),
at('address', setIfMissing({_type: 'address'})),
at('address.city', set('Oslo')),
]),
]
// get a projectId and dataset at sanity.io
const projectId = '<projectId>'
const dataset = '<dataset>'
// Submit mutations to the Sanity API
fetch(`https://${projectId}.api.sanity.io/v2023-08-01/data/mutate/${dataset}`, {
method: 'POST',
mode: 'cors',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(SanityEncoder.encode(mutations)),
})
.then(response => response.json())
.then(result => console.log(result))
突变创造者
变异
create(document: SanityDocument): 创建一个新文档createIfNotExists(document: SanityDocument): 如果不存在新文档, 则创建新文档createOrReplace(document: SanityDocument): 创建新文档或替换已存在的文档delete(documentId: SanityDocument): 删除文档(别名:del, (中文(简体) ),destroy(中文(简体) )patch(documentId: string, patches: Patch | Patch[], options?: {ifRevision?: string}): 补丁文档。 可以吗 可选择提供 arevisionId页:1 乐观锁定如果 当前文档修订与指定的修订不匹配,当应用时补丁突变会失败.
补丁
补丁是节点路径和操作的组合. 节点路径是一个 简化 杰森马克 路径或指向 文档中的特定节点。 行动就是其中之一 下级。 。 。 .
at(path: Path | string, operation: Operation): 从路径和操作中创建补丁
实例:
at('foo.bar', set('baz'))
// equivalent to the above
at(['foo', 'bar'], set('baz'))
at(['array[0]'], insert('baz'))
// Set a value deep into an array of objects addressed by `_key`
at(['people', {_key: 'xyz'}, 'name'], set('Bjørge'))
// equivalent to the above, using a serialized path:
at('people[_key=="xyz"].name', set('Bjørge'))
补丁操作
适用于所有数据类型的补丁操作
set(value: any): 将节点的值设定为给定valuesetIfMissing(value: any): 将节点的值设定为给定value如果节点没有值unset(): 从文档中删除节点
对象操作
assign(value: object): 将节点与给定值进行浅重合并. 如果节点是对象,则值会 合并到类似于Object.assign(<currentValue>, value)。 。 。 .unassign(attributes: string[]): 从现有值中删除给定属性.
阵列操作
prepend(items: any[]): 将给定的项目放在数组开头append(items: any[]): 将指定项目添加到数组的末尾insert(items: any | any[], position: "before" | "after", referenceItem: number | {_key: string}): 插入给定的 给定之前或之后的项目before或者说after目 录(续) 若为before或者说after未提供,项目将 插入到数组的起始或结尾.truncate(startIndex: number, endIndex?: number): 从数组中删除项目startIndex结束 时间endIndex如果endIndex未提供全部项目startIndex将被删除.replace(items: any | any[], referenceItem: number | {_key: string}): 替换referenceItem(电话:1 (212) 963-9084) 索引或键,带有给定item或者说items如果items是一个阵列,referenceItem改为: 以及其后出现的任何现有要素referenceItem将移到右边.upsert(items: any | any[], position: "before" | "after", referenceItem: number | {_key: string}): 提升一个或多个项目 输入数组。 如果项目匹配阵列中的现有项目, 现有的项目将被给定的替换 页:1 如果项目与任何现有项目不相匹配,将插入数组。 这个referenceItem指定一个参考项目,将缺失的项目放在相对位置。 若说. 如果不提供,则将在 数组的起始或结尾,取决于position编辑position选项可以用于指定项目在不插入时插入何处 匹配任何现有项目。 如果不提供,项目将在阵列末尾插入.
数量
inc(value: number): 按给定值增加数字dec(value: number): 以给定值减少数字
字符串操作
diffMatchPatch(patch: string): 在当前字符串中应用增量文本补丁。 更多信息 关于 diffMatch 选项。 。 。 .
高级实例
定义一组操作, 并将其变成可以应用到一组文档上的补丁突变
const patches = [
at("metadata", setIfMissing({})), // make sure metadata object exists
at("metadata.published", set(true)),
at("metadata.publishedAt", set(new Date().toISOString())),
]
const mutations = ["document-1", "document-2", "document-3"].map(id =>
patch(id, patches),
)
// commit mutations to datastore
commitMutations(mutations)
在本地文档上应用突变( 实验性)
变异可以用于文档的内存集合
import {applyInCollection} from '@bjoerge/mutiny/_unstable_apply'
import {createIfNotExists, del} from '@bjoerge/mutiny'
const initial = [{_id: 'deleteme', _type: 'foo'}]
const updated = applyInCollection(initial, [
createIfNotExists({_id: 'mydocument', _type: 'foo'}),
createIfNotExists({_id: 'anotherDocument', _type: 'foo'}),
del('deleteme'),
])
console.log(updated)
/*=>
[
{ _id: 'mydocument', _type: 'foo' },
{ _id: 'anotherDocument', _type: 'foo' }
]
*/
注:当对收藏物应用突变时,偏好完整性被保留. 这意味着如果一个突变实际上是一个 noop(例如没有实际改变),那么同样的对象引用会被返回.
import {applyInCollection} from '@bjoerge/mutiny/_unstable_apply'
import {at, createIfNotExists, patch, set} from '@bjoerge/mutiny'
const initial = [
{
_id: 'someDoc',
_type: 'foo',
value: 'ok',
nested: {value: 'something'},
otherNested: {message: 'something else'},
},
]
const updated = applyInCollection(initial, [
createIfNotExists({_id: 'someDoc', _type: 'foo'}),
patch('someDoc', [at('value', set('ok'))]),
patch('someDoc', [at('nested.value', set('something'))]),
])
// the mutation didn't cause anything to change
console.log(initial === updated)
//=> true
情况也是这样: 节点 不受变异影响:
import {applyInCollection} from '@bjoerge/mutiny/_unstable_apply'
import {at, createIfNotExists, patch, set} from '@bjoerge/mutiny'
const initial = [
{
_id: 'someDoc',
_type: 'foo',
value: 'ok',
nested: {value: 'something'},
otherNested: {message: 'something else'},
},
]
const updated = applyInCollection(initial, [
createIfNotExists({_id: 'someDoc', _type: 'foo'}),
patch('someDoc', [at('value', set('ok'))]),
patch('someDoc', [at('nested.value', set('something'))]),
patch('someDoc', [at('otherNested.message', set('hello'))]),
])
// the `nested` object unaffected by the mutation
console.log(initial[0].nested === updated[0].nested)
//=> true
将补丁突变应用到单个文档中
或者,一个补丁突变可以适用于单个文档,只要其id与该突变的文档id相匹配:
import {applyPatchMutation} from '@bjoerge/mutiny/_unstable_apply'
import {at, insert, patch, setIfMissing} from '@bjoerge/mutiny'
const document = {_id: 'test', _type: 'foo'}
const updated = applyPatchMutation(
document,
patch('test', [
at('title', setIfMissing('Foo')),
at('cities', setIfMissing([])),
at('cities', insert(['Oslo', 'San Francisco'], 'after', 0)),
]),
)
console.log(updated)
/*=>
{
_id: 'test',
_type: 'foo',
title: 'Foo',
cities: [ 'Oslo', 'San Francisco' ]
}
*/
与Sanity API的区别
为了更好地配合严格的类型系统,兵变在应用补丁时与Sanity API略有不同. 虽然您可以用兵变表达出的所有变异类型也可以被表示为"Sanity API变异",但反向并不一定是真实的;"Sanity API"(例如收听者)可能会产生不考虑当前文档的附加转换步骤而不能代表出兵变的补丁. 此外,在兵变中应用一个补丁与在几个账户上使用"Sanity API"应用同一补丁的行为不同:
set财务报告和审定财务报表setIfMissing不创建中间空对象 - 使用 Sanity API,set财务报告和审定财务报表setIfMissing如果沿着给定路径的任何对象已不存在,则会创建中间空对象。 单位mutiny,这些补丁将仅适用于已存在的对象.- 有限的Json匹配支持. Sanity突变支持一个强大的路径选择语法,用于同时瞄准多个文档节点 json- match 游戏。为简单起见,一个兵变补丁只能瞄准一个文件节点.