@aws-blocks/bb-distributed-table

中文文档
0.3.0发布于 2026/11/02Apache-2.0TypeScriptES Module构建来源已验证近 30 天下载 6.3万

结构化数据存储由DynamoDB支持,具有二级索引和丰富的查询能力.

中文使用文档
文档目录17 节
  1. API 密码
  2. 选项
  3. 密钥对象模式
  4. 查询
  5. 有条件的操作
  6. 阅读和计划演变
  7. 处理错误
  8. 实例
  9. 基础 CROUD
  10. 以按键排序条件查询
  11. TTL( 自动过期项目)
  12. 批量操作
  13. 环绕已存在的表格
  14. 最佳做法
  15. 缩放成本( AWS)
  16. 重复和安全默认( S)
  17. 地方发展

已分发 图表

结构化数据存储由DynamoDB支持,具有二级索引和丰富的查询能力.

何时使用 : 您需要通过多个字段查询,使用复合键,或者执行以排序为基础的范围查询. 对有关系,时间序列数据和需要多个索引的存取模式的实体有好处.

不使用时 : 如果您只需要单键检查, 请使用 KVStore。如果需要完整的 SQL(joins,聚合),则使用 Database。 。 。 .

设计与模拟等价细节 : 设计

API 密码

const table = new DistributedTable(scope, id, options)

类型推论( 重要 ): 执行 没有 通过一个单一的显式类型参数,例如 new DistributedTable<MyType>(...)。只做这样的针 T 并让密钥/索引的通用符号回到其广泛的默认值,这打破了密钥类型的推论—— get() 财务报告和审定财务报表 query({ where }) 然后会要求 每个 字段,而不只是关键字段。 要么让所有一般人推断(new DistributedTable(scope, id, { schema, key, indexes }) 没有明确 <...>),或通过所有三个通名. 请注意: as const 一个人做 没有 修复它.

方法回返说明
get(key)Promise<T | null>按主键获取单个项目 .
put(item, options?)Promise<void>存储一个物品。 覆盖, 除非设置条件 .
delete(key, options?)Promise<void>按主键删除项目 .
query(options)AsyncIterable<T>按索引或主键查询项目 .
scan(options?)AsyncIterable<T>完成所有项目。 精通大型数据集.
getBatch(keys)Promise<(T | null)[]>按键获取多个项目 .
putBatch(items)Promise<void>储存多件物品.
deleteBatch(keys)Promise<void>按键删除多个项目 .
DistributedTable.fromExisting(tableName)ExternalTableRef包好先前存在的DynamomDB表格.

只有运行时间. 数据方法get, (中文(简体) ), put, (中文(简体) ), delete, (中文(简体) ), query, (中文(简体) ), scan, (中文(简体) ), getBatch, (中文(简体) ), putBatch, (中文(简体) ), deleteBatch(按请求时间运行) ApiNamespace 方法, RawRoute 处理器、工作处理器或运行时脚本, 没有 在您的顶级 aws-blocks/index.ts。顶级代码运行于 CDK 合成期间,其中块解决其基础设施构造,其数据方法为 守护:顶级调用 Error 读取 DistributedTable.<method>() cannot be called during CDK synth. Data methods run at request time — …。对于种子数据,请从处理器内部或单独的运行时脚本中进行。 在模块范围构造块是好的;只有方法调用才能移动到处理器中.

正在收集 scan() 结果 : 喜欢 query(), (中文(简体) ), scan() 返回一个 AsyncIterable - 与 await Array.fromAsync(table.scan()) 或直线 for await. 偏爱 query() 结束 scan() (扫描仪读取每件物品).

选项

选项类型需求说明
schemaStandardSchemaV1对运行时验证计划(佐德,瓦利博特,ArkType等). 类型 T 根据计划推断.
keyTableKeyConfig<T>对主密钥配置 : { partitionKey, sortKey? }中必须存在字段名称.
indexesRecord<string, TableKeyConfig<T>>没有全球二级指数定义.
ttlkeyof T & string没有在指定的属性上启用 DynamoDB TTL 。 字段应当包含以秒计的Unix时间戳.
pointInTimeRecoveryboolean | { retentionDays: number }没有即时复苏(接续后援). true = 打开默认的35天窗口; false =关闭; { retentionDays: n } 继续 n- 日间窗口(1至35岁) (中文(简体) ). 堆栈默认值 defaults.pointInTimeRecovery (关于 BlocksPresets.production关闭在下面 sandbox) (中文(简体) ). 每GB-月备份存储的账单;更短的窗口修剪成本.
protection'disposable' | 'retained' | 'locked'没有表格的销毁有多难(spans去除政策+删除保护). 'disposable' = 随堆栈被删除; 'retained' = 堆栈删除时成为孤儿,但直接删除仍然有效; 'locked' =孤儿 财务报告和审定财务报表 删除保护。 省略时, 删除策略 + 删除保护跟随堆栈 defaults (单位:千美元)BlocksPresets.production ≈ 'locked', (中文(简体) ), sandbox ≈ 'disposable') (中文(简体) ).
encryption'aws-managed' | 'customer-managed' | ExternalKmsKeyRef没有At -rest 加密密钥. 'aws-managed' (默认)使用 aws/dynamodb KMS 密钥(可审计,无密钥充电); 'customer-managed' 提供专门的CMK; 通过 DistributedTable.fromKmsKey(arn) 以您拥有的现有CMK加密(可跨表格共享).
readValidation'off' | 'coerce' | 'strict'没有如何读取(get编号 :getBatch编号 :query编号 :scan将存储的项目与 schema。 。 。 . 'coerce' (单位:千美元)默认返回被胁迫值,并在失败时返回原始值+警告(从未丢出); 'strict' 掷出 ValidationFailed 关于不符合同的项目; 'off' 返回未验证的原始值。 见 阅读和计划演变。 。 。 .
tableExternalTableRef没有将已有的 DynamoDB 表格包起来, 而不是创建 。 Durable/加密选项被忽略——客户拥有表格的配置.
loggerChildLogger没有内部操作的可选日志。 省略时, 在警告级别创建默认 Logger readValidation: 'coerce' 后退警告浮出水面.

密钥对象模式

所有接受密钥的方法(get, (中文(简体) ), delete, (中文(简体) ), getBatch, (中文(简体) ), deleteBatch)用分区键字段取出一个密钥对象(如果定义了,则排序密钥字段)。 密钥类型是从您的策略和密钥配置中计算出来的 —— TypeScript 完全执行正确的字段 :

// Table with partition key + sort key
const orders = new DistributedTable(scope, 'orders', {
  schema: orderSchema,
  key: { partitionKey: 'userId', sortKey: 'orderId' },
});

// Key object requires both fields
await orders.get({ userId: 'alice', orderId: '001' });

// Table with partition key only
const settings = new DistributedTable(scope, 'settings', {
  schema: settingsSchema,
  key: { partitionKey: 'settingId' },
});

// Key object requires only the partition key
await settings.get({ settingId: 'theme' });

查询

query() 选择单个选项对象。 指定 index 以查询一个GSI,或省略它以查询主键。 这个 where 句式是类型安全的——字段名称和条件类型是从索引(或主密钥)定义中计算出来的.

// Query a GSI
for await (const order of orders.query({
  index: 'byStatus',
  where: { status: { equals: 'pending' } },
  limit: 10,
  order: 'desc',
})) {
  console.log(order);
}

// Query the primary key (omit index)
for await (const order of orders.query({
  where: { userId: { equals: 'alice' }, orderId: { beginsWith: '2024-' } },
})) {
  console.log(order);
}

提示 : 当将所有结果收集到数组时,使用 Array.fromAsync() 而不是手动循环 :

const pending = await Array.fromAsync(orders.query({
  index: 'byStatus',
  where: { status: { equals: 'pending' } },
}));

查询选项 :

外地类型需求说明
indexkeyof Indexes没有GSI 查询 。 关闭查询主密钥 .
whereKeyCondition<T, K>对关键条件。 分区密钥需要 { equals }排序密钥支持 equals, (中文(简体) ), greaterThan, (中文(简体) ), lessThan, (中文(简体) ), between, (中文(简体) ), beginsWith等 (中文(简体) ).
limitnumber没有要返回的最大项数 .
order'asc' | 'desc'没有排序键的方向 。 默认为 'asc'。 。 。 .

有条件的操作

两者 put 财务报告和审定财务报表 delete 接受可选条件:

// Only write if key doesn't exist (idempotent create)
await table.put(item, { ifNotExists: true });

// Only write if existing item's field matches (optimistic locking)
await table.put(updatedItem, { ifFieldEquals: { version: 3 } });

// Only delete if item exists
await table.delete(key, { ifExists: true });

// Only delete if field matches
await table.delete(key, { ifFieldEquals: { status: 'archived' } });

所有条件失败 error.name === DistributedTableErrors.ConditionalCheckFailed序列化为JSON-RPC 409 (冲突) 在模拟时间和AWS运行时间, 仅 ifFieldEquals 乐观-锁定冲突被标出可以挽回; ifNotExists 编号 : ifExists 存在断言 没有 可回收( 盲重试失败 ) .

无部分更新 : 没有 update() 或者说 patch() 方法。 要更改字段,请做一个读取-修改-写作—— get() 然后改变它 put() 整个东西回来。 为安全同步更新, 请通过 { ifFieldEquals: { version: <previous> } } 改为 put() 故此写入失败( 通过 ConditionalCheckFailed),如果另一个编剧同时更改了项目(乐观地锁定).

阅读和计划演变

写作总是以 schema。读取根据 readValidation 选项,此选项在方案更改后很重要:在旧方案下写的行可能不再匹配已宣布的类型 T 新增加的一个领域是: 缺席 从读取( 所以数值沉默地违反) T,则a .default() 既未适用,也未坚持回函,a 需要,无违约 字段使上面的读-修改-写周期 写入失败 作为 put() 拒绝留下的形状.

readValidation 有三个模式:

模式读取关于一个不符合同的项目
'coerce' (默认)返回图中的被强制输出(默认已填充,类型已缩小)返回时 原始内容 数值 + 记录一个警告 - 从不扔
'strict'对照计划进行验证掷出 ValidationFailed
'off'返回原始存储值,没有验证返回为-is

默认 'coerce' 关闭计划-进化差距

const orderSchema = z.object({
  orderId: z.string(),
  total: z.number(),
  currency: z.string().default('USD'),   // added in a later release
});

const orders = new DistributedTable(scope, 'orders', {
  schema: orderSchema,
  key: { partitionKey: 'orderId' },
  // readValidation: 'coerce' is the default
});

const order = await orders.get({ orderId: 'o1' }); // legacy row → { …, currency: 'USD' }
await orders.put({ ...order, total: 20 });          // round-trips without ValidationFailed

'coerce' 从不掷出 : 返回真正不能被胁迫的值(例如,没有默认要求的字段) 作为 有警告,所以无法恢复的行 保持可读的迁移和 get() 永远不要扔坏一行.

最佳强制(验证人-依赖). 强迫取决于计划 转换 它的投入。 Zod填充默认和铸造;一个只检查的标准Schema验证器(一些Valibot/ArkType schemas)验证而不转换,所以 'coerce' 返回这些值的不变值——它从未发明数据.

'coerce' 保存未在计划内保存的密钥. 许多计划验证时丢弃未识别的密钥( Zod 对象计划) .strip() ——然后,一个被读取的修改-写入会持续丢失。 为了避免这样, 'coerce' 被逼输出的深渊 覆盖原始存储项目: chema 输出赢得每个密钥( 默认被填充, 类型被收缩), 而属性 schema 不声明 —— 从一个更古老的chema 版本, 或列另一个作者拥有的 —— 是 保留。阵列被替换为批发(被胁迫阵列获胜),并保留嵌入的未知密钥。 因此,一个例行的读取-修改-写字从不默默地删除一个你没有触及的字段. (使用时) 'strict' 如果你想要一个计划不匹配被拒绝,或者 'off' 完全跳过计划通过。 )

选择 'strict' 用于将计划错配视为腐败和拒绝的表格(注:一行坏,然后整个失败) query编号 :scan编号 :getBatch) (中文(简体) ). 选择 'off' 对于热路径,您所信任的数据是通过此策略写入的,或者读取(并保存)行,您在迁移时尚不能强制.

处理错误

分布表所抛出的错误 error.name 您可以与 isBlocksError数字 :

常数error.name掷出时
DistributedTableErrors.ConditionalCheckFailedConditionalCheckFailedException一个 ifNotExists 编号 : ifExists 编号 : ifFieldEquals 条件失败 。 序列化为 HTTP 409 (冲突); 仅用于 ifFieldEquals 乐观冲突(不是) ifNotExists 编号 : ifExists) (中文(简体) ).
DistributedTableErrors.ValidationFailedValidationFailedException已配置的项目失败 schema 验证时间 put() 编号 : putBatch()。 。 。 .
DistributedTableErrors.InvalidQueryInvalidQueryException查询/条件形状错误: 缺失 where,未给出分区键为 { equals },未知索引,多排序条件,或空 ifFieldEquals呼叫器错误.
DistributedTableErrors.ItemTooLargeItemTooLargeExceptionA 类 put编号 :putBatch 超过 DynamoDB 400 KB 的每个项目大小限制.
DistributedTableErrors.BatchIncompleteBatchIncompleteException批量操作在重试预算( 持续节奏) 后未处理条目 。 AWS只运行时间 .
import { isBlocksError } from '@aws-blocks/core';
import { DistributedTableErrors } from '@aws-blocks/bb-distributed-table';

try {
  await table.put(item, { ifNotExists: true });
} catch (e: unknown) {
  if (isBlocksError(e, DistributedTableErrors.ConditionalCheckFailed)) {
    // item already exists
  }
  if (isBlocksError(e, DistributedTableErrors.ItemTooLarge)) {
    // item > 400 KB — split it or store a reference instead
  }
  throw e;
}

实例

基础 CROUD

这些例子使用Zod,但 schema 接受任何标准SchemaV1执行(Zod, Valibot, ArkType). 安装您选择的库, 例如 . npm install zod。 。 。 .

import { z } from 'zod';

const orderSchema = z.object({
  userId: z.string(),
  orderId: z.string(),
  total: z.number(),
  status: z.string(),
  createdAt: z.number(),
});

const orders = new DistributedTable(scope, 'orders', {
  schema: orderSchema,
  key: { partitionKey: 'userId', sortKey: 'orderId' },
});

export const api = new ApiNamespace(scope, 'api', (context) => ({
  async getOrder(userId: string, orderId: string) {
    return await orders.get({ userId, orderId });
  },
  async createOrder(order: z.infer<typeof orderSchema>) {
    await orders.put(order, { ifNotExists: true });
  },
  async deleteOrder(userId: string, orderId: string) {
    await orders.delete({ userId, orderId });
  },
}));

以按键排序条件查询

const orders = new DistributedTable(scope, 'orders', {
  schema: orderSchema,
  key: { partitionKey: 'userId', sortKey: 'orderId' },
  indexes: {
    byDate: { partitionKey: 'userId', sortKey: 'createdAt' },
  },
});

// Ctrl+Space on the where object shows: userId, createdAt
// userId requires { equals }, createdAt supports greaterThan, between, etc.
const results = [];
for await (const order of orders.query({
  index: 'byDate',
  where: {
    userId: { equals: 'alice' },
    createdAt: { greaterThan: Date.now() - 86400000 },
  },
})) {
  results.push(order);
}

TTL( 自动过期项目)

const sessions = new DistributedTable(scope, 'sessions', {
  schema: sessionSchema,
  key: { partitionKey: 'sessionId' },
  ttl: 'expiresAt',
});

// DynamoDB automatically deletes items after the TTL timestamp
await sessions.put({
  sessionId: 'abc123',
  userId: 'alice',
  expiresAt: Math.floor(Date.now() / 1000) + 3600, // 1 hour from now
});

批量操作

// Write many items
await orders.putBatch([order1, order2, order3]);

// Read many items
const items = await orders.getBatch([
  { userId: 'alice', orderId: '001' },
  { userId: 'bob', orderId: '002' },
]);

// Delete many items
await orders.deleteBatch([
  { userId: 'alice', orderId: '001' },
  { userId: 'bob', orderId: '002' },
]);

环绕已存在的表格

const legacy = new DistributedTable(scope, 'legacy', {
  schema: orderSchema,
  key: { partitionKey: 'userId', sortKey: 'orderId' },
  table: DistributedTable.fromExisting('my-existing-table'),
});

最佳做法

  • 为偶数数据分布设计分区键(例如, userId, (中文(简体) ), tenantId(中文(简体) )
  • 对范围查询使用排序键(例如:时间戳、字母顺序)
  • 定义已知访问模式的 GSIs 前置 —— 以后添加它们需要回填
  • 使用 { ifNotExists: true } 用于生成偶数
  • 使用 { ifFieldEquals } 当多个作者有可能时, 乐观的锁定
  • 偏爱 query() 结束 scan() ——扫描每件物品,价格昂贵

缩放成本( AWS)

  • 计费: PAY PER REQENT - 没有提供管理能力
  • 延迟 : 读取和写出数位数
  • 通过量 : 自动缩放, 表格大小无上限
  • 项目大小限制 : 每件400KB
  • GSI 限制 : 每表最多20个全球二级指数
  • 费用: ~每百万人有1.25美元,~每百万人有0.25美元
  • 重复性 : 99.99999999999%(119%),跨越3个AZ

重复和安全默认( S)

疲惫的姿势来自 堆栈宽度 BlocksDefaults 交给你 BlocksStack.create 编号 : BlocksBackend.create (单位:千美元)BlocksPresets.production 或者说 BlocksPresets.sandbox 从 @aws-blocks/core/cdk)——每块建筑块都读取同样的取号,所以一张表格的去除政策,去除保护,以及连续备份姿态都跟随了应用程序所选择的预设. 没有每个街区 sandboxMode 猜测.

下 BlocksPresets.production,每个表格中,本块规定船舶:

  • 即时恢复 启用( e)defaults.pointInTimeRecovery)——在过去35天恢复到任何一秒.
  • 保留 + 删除保护 (单位:千美元)defaults.removalPolicy = RETAIN, (中文(简体) ), defaults.deletionProtection = true)——既无倒叠倒地,也无流浪 cdk destroy/收音机删除可以擦去桌子,直到明确放松. (相当于 protection: 'locked'. ) (中文(简体) )
  • SSE - KMS (英语) 由AWS管理 aws/dynamodb 密钥 – 可通过 CloudTrail 进行验证的加密- rest 可不按每键收费.

下 BlocksPresets.sandbox 换个方式,PITR关闭, RemovalPolicy.DESTROY,删除保护(相当于 protection: 'disposable')——所以丢弃的堆栈保持廉价并 sandbox:destroy 是一个命令撕毁。 SSE-KMS 都保留在其中(加密不属于 BlocksDefaults 每块选项默认为 aws-managed) (中文(简体) ).

PITR不是免费的. 连续备份存储的点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点-点 它是默认的,因为无法恢复的数据损失通常是更糟糕的结果——但对于可再生的数据(caches,衍生表格)集 pointInTimeRecovery: false。 。 。 .

protection: 'locked'编号 :'retained' 孤体,堆栈删除的表格. 因为驱逐政策是 RETAIN,删除堆栈后留下表格(通过设计——您的数据存活)。 但表格名称是从区块的ID中衍生出来的 所以 后调用同一应用程序失败 Table already exists 直到你们删除已忽略的表格aws dynamodb delete-table中,如果 'locked')或导入到新堆栈中。 这是保留在删除中固有的;使用 protection: 'disposable' 对于您期望可以自由重现的表格.

索引跟随配置,而表格则在堆栈中. 删除一个索引(或整个) indexes 选项),从您的配置中并重新部署从表格中跳出。 当表格本身离开堆栈时(您删除堆栈,或去掉 DistributedTable 它的索引是孤寡的 'locked'编号 :'retained' 表格保存全部,所以导入到新堆栈不需要重建索引。 要告诉两者分开,GSI管理器读取了堆栈的模板. 如果在更新(或回滚更新)的清理阶段无法读取该索引,则该索引保持不变,并报告 DELETE_FAILED 用于表格的 GSI 自定义资源的事件(逻辑 ID 包含 gsiresource来命名表格和索引。 部署本身仍然成功,所以检查该事件的部署输出(或堆栈事件). 要删除您已经没有的索引, 运行 aws dynamodb update-table --table-name <table> --global-secondary-index-updates '[{"Delete":{"IndexName":"<index>"}}]'; DynamoDB每次呼叫需要一个索引变化,所以等待每个删除在下个之前完成.

每个堆栈默认值每个表都是压倒性的(每块选项总是胜过) defaults:

// Cost-sensitive prod table: keep it protected, skip PITR's backup cost
const cache = new DistributedTable(scope, 'cache', {
  schema, key: { partitionKey: 'id' },
  pointInTimeRecovery: false,
});

// Long-lived data you still want to be able to delete directly
const staging = new DistributedTable(scope, 'staging', {
  schema, key: { partitionKey: 'id' },
  protection: 'retained',   // survives stack delete, but not deletion-protected
});

// Compliance-strict table: dedicated customer-managed KMS key
const ledger = new DistributedTable(scope, 'ledger', {
  schema, key: { partitionKey: 'id' },
  encryption: 'customer-managed',
});

// Share one customer-managed key across several tables (one key, one bill)
const key = DistributedTable.fromKmsKey('arn:aws:kms:us-east-1:111122223333:key/abcd-1234');
const orders = new DistributedTable(scope, 'orders', {
  schema, key: { partitionKey: 'id' },
  encryption: key,
});
const events = new DistributedTable(scope, 'events', {
  schema, key: { partitionKey: 'id' },
  encryption: key,
});

压倒性总是会战胜环境默认,这样你就可以在沙盒中(或放轻松一分)明确强制一个完全耐用,受保护的桌子. 当你通过自己的桌子 fromExisting(),这些选项都不适用——您拥有该表的配置.

customer-managed 每表提供专用CMK ——一款配有十几张客户管理表的应用程序获得一打KMS密钥(~每个月1美元,外加请求费). 要在多个表格中共享一个密钥, 请创建一个密钥并传递 DistributedTable.fromKmsKey(keyArn) 作为 encryption 选项。 使用默认 'aws-managed' 除非表格需要自己的旋转/关键政策控制.

地方发展

模拟数据持续到磁盘 .bb-data/{fullId}/ 跨 Dev 服务器重启 。 擦拭为 rm -rf .bb-data。模拟验证了400 KB 项的尺寸限制、 计划验证以及有条件的检查失败, 符合 AWS 行为。 索引查询是通过内膜过滤执行的——正确性得到保留,但性能特征与DynamoDB不同.

版本与发布记录

@aws-blocks/bb-distributed-table 共发布 15 个版本,首次发布于 2026/06/16;过去 12 个月发布了 15 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.3.0latest2026/11/025 天前
0.2.22026/10/1622 天前
0.0.0-canary.esql-canary.c93c81b.1791235863canary-esql-canary2026/10/061 个月前
0.2.12026/10/051 个月前
0.0.0-canary.esql-canary.f7f39ac.17909891272026/10/031 个月前
0.0.0-canary.ci-publish-canary-npm.f53dfdc.1790988617canary-ci-publish-canary-npm2026/10/031 个月前

关于 @aws-blocks/bb-distributed-table 的常见问题

@aws-blocks/bb-distributed-table 是什么?

结构化数据存储由DynamoDB支持,具有二级索引和丰富的查询能力.

如何安装 @aws-blocks/bb-distributed-table?

在项目目录运行 npm install @aws-blocks/bb-distributed-table,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:constructs(^10.6.0)、aws-cdk-lib(^2.257.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@aws-blocks/bb-distributed-table 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@aws-blocks/bb-distributed-table 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@aws-blocks/bb-distributed-table 可以商用吗?

@aws-blocks/bb-distributed-table 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@aws-blocks/bb-distributed-table 的下载量有多少?

根据 npm 官方下载统计,@aws-blocks/bb-distributed-table 在 2026/10/07 – 2026/11/05 这 30 天内被下载 63,453 次,日均约 2,115 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@aws-blocks/bb-distributed-table 还在维护吗?

最新版本 0.3.0 发布于 2026/11/02(5 天前);至今共发布 15 个版本,其中过去 12 个月发布了 15 个;首次发布于 2026/06/16。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。