Skip to content

xesam/js-proxy-views

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

proxy-views.js

让普通 JavaScript 对象变得更智能的轻量级工具库

Make plain JavaScript objects smarter with lightweight proxy views

🇨🇳 中文 | 🇺🇸 English


🇨🇳 中文文档 {#中文文档}

✨ 核心特性

  • 🔒 StrictView: 严格模式,只允许访问已定义的属性
  • 🔗 AliasView: 为复杂嵌套属性创建简洁别名
  • ⛓️ ChainView: 将多个字典链接成单一只读视图
  • 🛡️ MissingView: 基础包装,自定义缺失属性处理
  • 📦 零依赖: 纯 JavaScript 实现,无外部依赖
  • 🎯 非侵入: 不修改原始对象,只提供包装视图

📦 安装

npm install proxy-views

🚀 快速开始

1. ChainView - 链式字典视图

将多个字典链接成一个只读视图,支持链式查找和唯一遍历。

const { ChainView } = require('proxy-views');

const defaults = { theme: 'light', lang: 'en', debug: false };
const userPrefs = { theme: 'dark', lang: 'zh' };
const session = { debug: true, user: 'alice' };

const config = new ChainView(userPrefs, defaults, session);

// 链式查找:从第一个字典开始找,找不到继续向后找
console.log(config.theme); // 'dark' (来自 userPrefs)
console.log(config.debug); // true (来自 session)
console.log(config.port); // undefined (不存在)

// 只读访问:不能修改
config.newProp = 'value'; // Error: Cannot set property 'newProp' on ChainView (read-only)

// 遍历所有唯一键
for (const key of config) {
  console.log(key, config[key]);
}
// 输出: theme dark, lang zh, debug true, user alice

// 获取所有键
console.log(Object.keys(config)); // ['theme', 'lang', 'debug', 'user']
console.log(config.length); // 4

2. StrictView - 严格模式

防止拼写错误或访问不存在的属性,让你的代码更安全。

const { StrictView } = require('proxy-views');

const user = {
  name: '张三',
  age: 25,
  address: { city: '北京', street: '中关村大街' }
};

const safeUser = new StrictView(user);

// ✅ 正常访问
console.log(safeUser.name); // '张三'
console.log(safeUser.address.city); // '北京'

// ❌ 错误访问会抛出明确的错误
console.log(safeUser.nmae); // Error: Property "nmae" is not defined

2. AliasView - 属性别名

为深层嵌套属性创建简洁的别名,告别冗长的属性链。

const { AliasView } = require('proxy-views');

const config = {
  server: {
    database: {
      host: 'localhost',
      port: 5432,
      credentials: { username: 'admin', password: 'secret' }
    }
  }
};

const view = new AliasView(config);

// 创建别名
view.alias('server.database.host', 'dbHost');
view.alias('server.database.port', 'dbPort');

// 🎉 简洁访问
console.log(view.dbHost); // 'localhost'
console.log(view.dbPort); // 5432

// 修改会同步更新原始对象
view.dbHost = 'prod.example.com';
console.log(config.server.database.host); // 'prod.example.com'

批量创建别名

const view = new AliasView(data);

// 多种方式
view.alias('user.name', ['displayName', 'nickname']);
view.alias('user.email', 'email', 'mail', 'userEmail');
view.alias('settings.theme', ['theme', 'colorScheme'], 'uiTheme');

数据导出

const view = new AliasView({ name: '王五', age: 30 });
view.alias('name', 'username');

// 完整导出
console.log(view.toJSON());
// { name: '王五', age: 30, username: '王五' }

// 只导出别名
console.log(view.toJSON({ target: false, alias: true }));
// { username: '王五' }

🎯 实际应用场景

1. 配置管理

const config = new AliasView(appConfig);
config.alias('database.connection.host', 'dbHost');
const connStr = `${config.dbHost}:${config.dbPort}`;

2. API 响应简化

const user = new AliasView(apiResponse);
user.alias('user.profile.display_name', 'name');
setUserInfo({ name: user.name });

3. 表单数据映射

const form = new AliasView(apiData);
form.alias('customer.billing_address.street', 'billingStreet');

📋 API 参考

StrictView

  • new StrictView(object) - 创建严格视图
  • 只能访问原始对象中存在的属性

AliasView

  • new AliasView(object) - 创建别名视图
  • view.alias(originPath, ...aliasNames) - 创建别名
  • view.toJSON(options) - 导出数据

ChainView

  • new ChainView(dict1, dict2, ...) - 创建链式字典视图
  • 只读访问,支持链式查找
  • 支持 Object.keys(), for...of, Object.entries() 等遍历方法

🇺🇸 English Documentation {#english-documentation}

✨ Core Features

  • 🔒 StrictView: Strict mode, only allow access to defined properties
  • 🔗 AliasView: Create simple aliases for complex nested properties
  • ⛓️ ChainView: Chain multiple dictionaries into a single read-only view
  • 🛡️ MissingView: Basic wrapper with custom missing property handling
  • 📦 Zero Dependencies: Pure JavaScript implementation, no external deps
  • 🎯 Non-invasive: Doesn't modify original object, only provides wrapper view

📦 Installation

npm install proxy-views

🚀 Quick Start

1. ChainView - Chain Dictionary View

Chain multiple dictionaries into a single read-only view with chain lookup and unique iteration.

const { ChainView } = require('proxy-views');

const defaults = { theme: 'light', lang: 'en', debug: false };
const userPrefs = { theme: 'dark', lang: 'zh' };
const session = { debug: true, user: 'alice' };

const config = new ChainView(userPrefs, defaults, session);

// Chain lookup: search from first dict, continue to next if not found
console.log(config.theme); // 'dark' (from userPrefs)
console.log(config.debug); // true (from session)
console.log(config.port); // undefined (not found)

// Read-only: cannot modify
config.newProp = 'value'; // Error: Cannot set property 'newProp' on ChainView (read-only)

// Iterate all unique keys
for (const key of config) {
  console.log(key, config[key]);
}
// Output: theme dark, lang zh, debug true, user alice

// Get all keys
console.log(Object.keys(config)); // ['theme', 'lang', 'debug', 'user']
console.log(config.length); // 4

2. StrictView - Strict Mode

Prevent typos or accessing non-existent properties, making your code safer.

const { StrictView } = require('proxy-views');

const user = {
  name: 'John',
  age: 25,
  address: { city: 'Beijing', street: 'Zhongguancun Street' }
};

const safeUser = new StrictView(user);

// ✅ Normal access
console.log(safeUser.name); // 'John'
console.log(safeUser.address.city); // 'Beijing'

// ❌ Error access throws clear error
console.log(safeUser.nmae); // Error: Property "nmae" is not defined

2. AliasView - Property Aliases

Create simple aliases for deeply nested properties, eliminating long property chains.

const { AliasView } = require('proxy-views');

const config = {
  server: {
    database: {
      host: 'localhost',
      port: 5432,
      credentials: { username: 'admin', password: 'secret' }
    }
  }
};

const view = new AliasView(config);

// Create aliases
view.alias('server.database.host', 'dbHost');
view.alias('server.database.port', 'dbPort');

// 🎉 Simple access
console.log(view.dbHost); // 'localhost'
console.log(view.dbPort); // 5432

// Changes sync to original object
view.dbHost = 'prod.example.com';
console.log(config.server.database.host); // 'prod.example.com'

Batch Alias Creation

const view = new AliasView(data);

// Multiple ways
view.alias('user.name', ['displayName', 'nickname']);
view.alias('user.email', 'email', 'mail', 'userEmail');
view.alias('settings.theme', ['theme', 'colorScheme'], 'uiTheme');

Data Export

const view = new AliasView({ name: 'John', age: 30 });
view.alias('name', 'username');

// Full export
console.log(view.toJSON());
// { name: 'John', age: 30, username: 'John' }

// Only aliases
console.log(view.toJSON({ target: false, alias: true }));
// { username: 'John' }

🎯 Real-world Use Cases

1. Configuration Management

const config = new AliasView(appConfig);
config.alias('database.connection.host', 'dbHost');
const connStr = `${config.dbHost}:${config.dbPort}`;

2. API Response Simplification

const user = new AliasView(apiResponse);
user.alias('user.profile.display_name', 'name');
setUserInfo({ name: user.name });

3. Form Data Mapping

const form = new AliasView(apiData);
form.alias('customer.billing_address.street', 'billingStreet');

📋 API Reference

StrictView

  • new StrictView(object) - Create strict view
  • Only access properties that exist in original object

AliasView

  • new AliasView(object) - Create alias view
  • view.alias(originPath, ...aliasNames) - Create aliases
  • view.toJSON(options) - Export data

ChainView

  • new ChainView(dict1, dict2, ...) - Create chain dictionary view
  • Read-only access with chain lookup
  • Supports Object.keys(), for...of, Object.entries() traversal methods

🤝 Contributing

欢迎提交 Issue 和 Pull Request! / Contributions are welcome!

📄 License

MIT License - see LICENSE file

📊 Changelog

0.0.2

  • Added ChainView: Chain dictionary view for read-only linking of multiple dictionaries
  • Supports chain lookup and unique key iteration
  • Fully compatible with standard iteration methods (Object.keys, for...of, Object.entries, etc.)

0.0.1

  • Initial release with MissingView, StrictView and AliasView base implementations

About

Some wrapper views for Plain Data Object with [Proxy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy). Make Data Object more semantic and easier to use.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors